arch: samd5e5 : Oneshot, freerun and tickless available support. All support runs on Timer/Counter (TC).
Some fixes in external interrupt controller (EIC) and clockconfig. Testing: - Build check only. Signed-off-by: Leomar Mateus Radke <leomar@falker.com.br>
This commit is contained in:
parent
171cc38ac2
commit
f5912b5cba
@ -258,6 +258,7 @@ config ARCH_CHIP_SAML2X
|
||||
config ARCH_CHIP_SAMD5X
|
||||
bool "Microchip SAMD5x"
|
||||
select ARCH_CORTEXM4
|
||||
select ARCH_HAVE_TICKLESS
|
||||
---help---
|
||||
Microchip SAMD5X (ARM Cortex-M4)
|
||||
|
||||
|
@ -321,6 +321,10 @@ config SAMD5E5_HAVE_SERCOM7
|
||||
bool
|
||||
default n
|
||||
|
||||
config SAMD5E5_HAVE_TC
|
||||
bool
|
||||
default n
|
||||
|
||||
config SAMD5E5_HAVE_TC4
|
||||
bool
|
||||
default n
|
||||
@ -341,6 +345,22 @@ config SAMD5E5_SERCOM
|
||||
bool
|
||||
default n
|
||||
|
||||
config SAMD5E5_TC
|
||||
bool
|
||||
default y
|
||||
|
||||
config SAMD5E5_HAVE_TC4
|
||||
bool
|
||||
default n
|
||||
|
||||
config SAMD5E5_HAVE_TC5
|
||||
bool
|
||||
default n
|
||||
|
||||
config SAMD5E5_HAVE_TC6
|
||||
bool
|
||||
default n
|
||||
|
||||
config SAMD5E5_AC
|
||||
bool "Analog Comparator"
|
||||
default n
|
||||
@ -429,38 +449,90 @@ config SAMD5E5_SERCOM7
|
||||
config SAMD5E5_TC0
|
||||
bool "Timer/Counter 0"
|
||||
default n
|
||||
depends on SAMD5E5_TC
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_TC1
|
||||
bool "Timer/Counter 1"
|
||||
default n
|
||||
depends on SAMD5E5_TC
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_TC2
|
||||
bool "Timer/Counter 2"
|
||||
default n
|
||||
depends on SAMD5E5_TC
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_TC3
|
||||
bool "Timer/Counter 3"
|
||||
default n
|
||||
depends on SAMD5E5_TC
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_TC4
|
||||
bool "Timer/Counter 4"
|
||||
default n
|
||||
depends on SAMD5E5_HAVE_TC4
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_TC5
|
||||
bool "Timer/Counter 5"
|
||||
default n
|
||||
depends on SAMD5E5_HAVE_TC5
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_TC6
|
||||
bool "Timer/Counter 6"
|
||||
default n
|
||||
depends on SAMD5E5_HAVE_TC6
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_TC7
|
||||
bool "Timer/Counter 7"
|
||||
default n
|
||||
depends on SAMD5E5_HAVE_TC7
|
||||
select SAMD5E5_HAVE_TC
|
||||
|
||||
config SAMD5E5_ONESHOT
|
||||
bool "TC one-shot wrapper"
|
||||
default n if !SCHED_TICKLESS
|
||||
default y if SCHED_TICKLESS
|
||||
---help---
|
||||
Enable a wrapper around the low level timer/counter functions to
|
||||
support one-shot timer.
|
||||
|
||||
config SAMD5E5_FREERUN
|
||||
bool "TC free-running wrapper"
|
||||
default n if !SCHED_TICKLESS
|
||||
default y if SCHED_TICKLESS
|
||||
---help---
|
||||
Enable a wrapper around the low level timer/counter functions to
|
||||
support a free-running timer.
|
||||
|
||||
if SCHED_TICKLESS
|
||||
|
||||
config SAMD5E5_TICKLESS_ONESHOT
|
||||
int "Tickless one-shot timer channel"
|
||||
default 2
|
||||
range 0 7
|
||||
---help---
|
||||
If the Tickless OS feature is enabled, the one clock must be
|
||||
assigned to provided the one-shot timer needed by the OS.
|
||||
NOTE: Use even timers (0, 2 or 4) because timers are program
|
||||
in 32-bit mode (1, 3 and 5 are slaves).
|
||||
|
||||
config SAMD5E5_TICKLESS_FREERUN
|
||||
int "Tickless free-running timer channel"
|
||||
default 4
|
||||
range 0 7
|
||||
---help---
|
||||
If the Tickless OS feature is enabled, the one clock must be
|
||||
assigned to provided the free-running timer needed by the OS.
|
||||
NOTE: Use even timers (0, 2 or 4) because timers are program
|
||||
in 32-bit mode (1, 3 and 5 are slaves).
|
||||
|
||||
endif
|
||||
|
||||
config SAMD5E5_USB
|
||||
bool "USB"
|
||||
|
@ -51,7 +51,7 @@
|
||||
/* EIC register offsets *********************************************************************/
|
||||
|
||||
#define SAM_EIC_CTRLA_OFFSET 0x0000 /* Control A register */
|
||||
#define SAM_EIC_NMITRCL_OFFSET 0x0001 /* Non-maskable interrupt control register */
|
||||
#define SAM_EIC_NMICTRL_OFFSET 0x0001 /* Non-maskable interrupt control register */
|
||||
#define SAM_EIC_NMIFLAG_OFFSET 0x0002 /* Non-maskable interrupt flasg status and clear register */
|
||||
#define SAM_EIC_SYNCBUSY_OFFSET 0x0004 /* Synchronization busy register */
|
||||
#define SAM_EIC_EVCTRL_OFFSET 0x0008 /* Event control register */
|
||||
@ -68,7 +68,7 @@
|
||||
/* EIC register addresses *******************************************************************/
|
||||
|
||||
#define SAM_EIC_CTRLA (SAM_EIC_BASE + SAM_EIC_CTRLA_OFFSET)
|
||||
#define SAM_EIC_NMITRCL (SAM_EIC_BASE + SAM_EIC_NMITRCL_OFFSET)
|
||||
#define SAM_EIC_NMICTRL (SAM_EIC_BASE + SAM_EIC_NMICTRL_OFFSET)
|
||||
#define SAM_EIC_NMIFLAG (SAM_EIC_BASE + SAM_EIC_NMIFLAG_OFFSET)
|
||||
#define SAM_EIC_SYNCBUSY (SAM_EIC_BASE + SAM_EIC_SYNCBUSY_OFFSET)
|
||||
#define SAM_EIC_EVCTRL (SAM_EIC_BASE + SAM_EIC_EVCTRL_OFFSET)
|
||||
@ -86,9 +86,9 @@
|
||||
|
||||
/* Control A register */
|
||||
|
||||
#define EIC_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */
|
||||
#define EIC_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */
|
||||
#define EIC_CTRLA_CKSEL (1 << 4) /* Bit 4: Clock selection */
|
||||
#define EIC_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */
|
||||
#define EIC_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */
|
||||
#define EIC_CTRLA_CKSEL (1 << 4) /* Bit 4: Clock selection */
|
||||
# define EIC_CTRLA_CKSEL_GCLK_EIC (0) /* 0=EIC clocked by GCLK_EIC */
|
||||
# define EIC_CTRLA_CKSEL_CLK_ULP32K EIC_CTRLA_CKSEL /* 1=EIC clocked by CLK_ULP32K */
|
||||
|
||||
@ -102,8 +102,8 @@
|
||||
# define EIC_NMITRCL_NMISENSE_BOTH (3 << EIC_NMITRCL_NMISENSE_SHIFT) /* Both edge detection */
|
||||
# define EIC_NMITRCL_NMISENSE_HIGH (4 << EIC_NMITRCL_NMISENSE_SHIFT) /* High level detection */
|
||||
# define EIC_NMITRCL_NMISENSE_LOW (5 << EIC_NMITRCL_NMISENSE_SHIFT) /* Low level detection */
|
||||
#define EIC_NMITRCL_NMIFLTEN (1 << 3) /* Bit 3: Non-maskable interrupt filter enable */
|
||||
#define EIC_NMITRCL_ASYNC (1 << 4) /* Bit 4: Asynchronous edge detection mode */
|
||||
#define EIC_NMITRCL_NMIFLTEN (1 << 3) /* Bit 3: Non-maskable interrupt filter enable */
|
||||
#define EIC_NMITRCL_ASYNC (1 << 4) /* Bit 4: Asynchronous edge detection mode */
|
||||
|
||||
/* Non-maskable interrupt flas status and clear register */
|
||||
|
||||
@ -142,7 +142,7 @@
|
||||
|
||||
/* Configuration 0 register */
|
||||
|
||||
#define EIC_CONFIG0_FILTEN(n) (3 + ((n) << 2)) /* Filter n enable, n=0-7 */
|
||||
#define EIC_CONFIG0_FILTEN(n) (0x8 << ((n) << 2)) /* Filter n enable, n=0-7 */
|
||||
#define EIC_CONFIG0_SENSE_SHIFT(n) ((n) << 2) /* Filter n input sense, n=0-7 */
|
||||
#define EIC_CONFIG0_SENSE_MASK(n) (7 << EIC_CONFIG0_SENSE_SHIFT(n))
|
||||
# define EIC_CONFIG0_SENSE_NONE(n) (0 << EIC_CONFIG0_SENSE_SHIFT(n)) /* No detection */
|
||||
@ -154,7 +154,7 @@
|
||||
|
||||
/* Configuration 1 register */
|
||||
|
||||
#define EIC_CONFIG1_FILTEN(n) (3 + (((n) - 8) << 2)) /* Filter n enable, n=8-15 */
|
||||
#define EIC_CONFIG1_FILTEN(n) (0x8 << (((n) - 8) << 2)) /* Filter n enable, n=8-15 */
|
||||
#define EIC_CONFIG1_SENSE_SHIFT(n) (((n) - 8) << 2) /* Filter n input sense, n=8-17 */
|
||||
#define EIC_CONFIG1_SENSE_MASK(n) (7 << EIC_CONFIG1_SENSE_SHIFT(n))
|
||||
# define EIC_CONFIG1_SENSE_NONE(n) (0 << EIC_CONFIG1_SENSE_SHIFT(n)) /* No detection */
|
||||
@ -198,10 +198,10 @@
|
||||
# define EIC_DPRESCALER_PRESCALER0_DIV64 (5 << EIC_DPRESCALER_PRESCALER0_SHIFT) /* EIC clock divided by 64 */
|
||||
# define EIC_DPRESCALER_PRESCALER0_DIV128 (6 << EIC_DPRESCALER_PRESCALER0_SHIFT) /* EIC clock divided by 128 */
|
||||
# define EIC_DPRESCALER_PRESCALER0_DIV256 (7 << EIC_DPRESCALER_PRESCALER0_SHIFT) /* EIC clock divided by 256 */
|
||||
#define EIC_DPRESCALER_STATES0 (1 << 3) /* Bit 3: Debouncer number of states. EXTINT 0-7 */
|
||||
# define EIC_DPRESCALER_STATES0_3 (0) /* 3 low frequency samples */
|
||||
# define EIC_DPRESCALER_STATES0_7 EIC_DPRESCALER_STATES0 /* 7 low frequency samples */
|
||||
#define EIC_DPRESCALER_PRESCALER1_SHIFT (4) /* Bitx 4-6: Debouncer Prescaler. EXTINT 8-15 */
|
||||
#define EIC_DPRESCALER_STATES0 (1 << 3) /* Bit 3: Debouncer number of states. EXTINT 0-7 */
|
||||
# define EIC_DPRESCALER_STATES0_3 (0) /* 3 low frequency samples */
|
||||
# define EIC_DPRESCALER_STATES0_7 EIC_DPRESCALER_STATES0 /* 7 low frequency samples */
|
||||
#define EIC_DPRESCALER_PRESCALER1_SHIFT (4) /* Bitx 4-6: Debouncer Prescaler. EXTINT 8-15 */
|
||||
#define EIC_DPRESCALER_PRESCALER1_MASK (7 << EIC_DPRESCALER_PRESCALER1_SHIFT)
|
||||
# define EIC_DPRESCALER_PRESCALER1_DIV2 (0 << EIC_DPRESCALER_PRESCALER1_SHIFT) /* EIC clock divided by 2 */
|
||||
# define EIC_DPRESCALER_PRESCALER1_DIV4 (1 << EIC_DPRESCALER_PRESCALER1_SHIFT) /* EIC clock divided by 4 */
|
||||
@ -211,12 +211,12 @@
|
||||
# define EIC_DPRESCALER_PRESCALER1_DIV64 (5 << EIC_DPRESCALER_PRESCALER1_SHIFT) /* EIC clock divided by 64 */
|
||||
# define EIC_DPRESCALER_PRESCALER1_DIV128 (6 << EIC_DPRESCALER_PRESCALER1_SHIFT) /* EIC clock divided by 128 */
|
||||
# define EIC_DPRESCALER_PRESCALER1_DIV256 (7 << EIC_DPRESCALER_PRESCALER1_SHIFT) /* EIC clock divided by 256 */
|
||||
#define EIC_DPRESCALER_STATES1 (1 << 7) /* Bit 7: Debouncer number of states. EXTINT 8-15 */
|
||||
# define EIC_DPRESCALER_STATES1_3 (0) /* 3 low frequency samples */
|
||||
# define EIC_DPRESCALER_STATES1_7 EIC_DPRESCALER_STATES1 /* 7 low frequency samples */
|
||||
#define EIC_DPRESCALER_TICKON (1 << 16) /* Bit 16: Pin Sampler frequency selection */
|
||||
# define EIC_DPRESCALER_TICKON_GCLKEIC (0) /* Bounce sampler uses GCLK_EIC */
|
||||
# define EIC_DPRESCALER_TICKON_LFCLK EIC_DPRESCALER_TICKON /* Bounce sampler uses low frequency clock */
|
||||
#define EIC_DPRESCALER_STATES1 (1 << 7) /* Bit 7: Debouncer number of states. EXTINT 8-15 */
|
||||
# define EIC_DPRESCALER_STATES1_3 (0) /* 3 low frequency samples */
|
||||
# define EIC_DPRESCALER_STATES1_7 EIC_DPRESCALER_STATES1 /* 7 low frequency samples */
|
||||
#define EIC_DPRESCALER_TICKON (1 << 16) /* Bit 16: Pin Sampler frequency selection */
|
||||
# define EIC_DPRESCALER_TICKON_GCLKEIC (0) /* Bounce sampler uses GCLK_EIC */
|
||||
# define EIC_DPRESCALER_TICKON_LFCLK EIC_DPRESCALER_TICKON /* Bounce sampler uses low frequency clock */
|
||||
|
||||
/* Pin state */
|
||||
|
||||
@ -249,7 +249,7 @@
|
||||
********************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Functions
|
||||
* Public Functions Prototypes
|
||||
********************************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_SAMD5E5_HARDWARE_SAM_EIC_H */
|
||||
|
479
arch/arm/src/samd5e5/hardware/sam_tc.h
Normal file
479
arch/arm/src/samd5e5/hardware/sam_tc.h
Normal file
@ -0,0 +1,479 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/hardware/sam_tc.h
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAMD5E5_CHIP_SAMD_TC_H
|
||||
#define __ARCH_ARM_SRC_SAMD5E5_CHIP_SAMD_TC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "hardware/sam_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* TC - COUNTx mode register offsets */
|
||||
|
||||
#define SAM_TC_CTRLA_OFFSET 0x0000 /* Control A register */
|
||||
#define SAM_TC_CTRLBCLR_OFFSET 0x0004 /* Control B clear register */
|
||||
#define SAM_TC_CTRLBSET_OFFSET 0x0005 /* Control B Set register */
|
||||
#define SAM_TC_EVCTRL_OFFSET 0x0006 /* Event Control registerr */
|
||||
#define SAM_TC_INTENCLR_OFFSET 0x0008 /* Interrupt Enable Clear register */
|
||||
#define SAM_TC_INTENSET_OFFSET 0x0009 /* Interrupt Enable Set register */
|
||||
#define SAM_TC_INTFLAG_OFFSET 0x000A /* Interrupt Flag Status and Clear register */
|
||||
#define SAM_TC_STATUS_OFFSET 0x000B /* Status register */
|
||||
#define SAM_TC_WAVE_OFFSET 0x000C /* Waveform Generation Control register */
|
||||
#define SAM_TC_DRVCTRL_OFFSET 0x000D /* Driver Control register */
|
||||
#define SAM_TC_DBGCTRL_OFFSET 0x000F /* Debug Control register */
|
||||
#define SAM_TC_SYNCBUSY_OFFSET 0x0010 /* Synchronization Busy register*/
|
||||
#define SAM_TC_COUNT_OFFSET 0x0014 /* Counter Value register */
|
||||
|
||||
/* TC-8bits mode register offsets */
|
||||
|
||||
#define SAM_TC_COUNT8_PER_OFFSET 0x001B /* Period Value, 8-bit Mode register */
|
||||
#define SAM_TC_COUNT8_CC0_OFFSET 0x001C /* Channel 0 Compare/Capture Value, 8-bit Mode register */
|
||||
#define SAM_TC_COUNT8_CC1_OFFSET 0x001D /* Channel 1 Compare/Capture Value, 8-bit Mode register */
|
||||
#define SAM_TC_COUNT8_PERBUF_OFFSET 0x002F /* Period Buffer Value, 8-bit Mode register */
|
||||
#define SAM_TC_COUNT8_CCBUF0_OFFSET 0x0030 /* Channel 0 Compare Buffer Value, 8-bit Mode register */
|
||||
#define SAM_TC_COUNT8_CCBUF1_OFFSET 0x0031 /* Channel 1 Compare Buffer Value, 8-bit Mode register */
|
||||
|
||||
/* TC-16bits mode register offsets */
|
||||
|
||||
#define SAM_TC_COUNT16_CC0_OFFSET 0x001C /* Channel 0 Compare/Capture Value, 16-bit Mode register */
|
||||
#define SAM_TC_COUNT16_CC1_OFFSET 0x001E /* Channel 1 Compare/Capture Value, 16-bit Mode register */
|
||||
#define SAM_TC_COUNT16_CCBUF0_OFFSET 0x0030 /* Channel 0 Compare Buffer Value, 16-bit Mode register */
|
||||
#define SAM_TC_COUNT16_CCBUF1_OFFSET 0x0032 /* Channel 1 Compare Buffer Value, 16-bit Mode register */
|
||||
|
||||
/* TC-32bits mode register offsets */
|
||||
|
||||
#define SAM_TC_COUNT32_CC0_OFFSET 0x001C /* Channel 0 Compare/Capture Value, 32-bit Mode register */
|
||||
#define SAM_TC_COUNT32_CC1_OFFSET 0x0020 /* Channel 1 Compare/Capture Value, 32-bit Mode register */
|
||||
#define SAM_TC_COUNT32_CCBUF0_OFFSET 0x0030 /* Channel 0 Compare Buffer Value, 32-bit Mode register */
|
||||
#define SAM_TC_COUNT32_CCBUF1_OFFSET 0x0034 /* Channel 1 Compare Buffer Value, 32-bit Mode register */
|
||||
|
||||
/* TCx register addresses */
|
||||
|
||||
#define SAM_TC0_CTRLA (SAM_TC0_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC0_CTRLBCLR (SAM_TC0_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC0_CTRLBSET (SAM_TC0_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC0_EVCTRL (SAM_TC0_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC0_INTENCLR (SAM_TC0_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC0_INTENSET (SAM_TC0_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC0_INTFLAG (SAM_TC0_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC0_STATUS (SAM_TC0_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC0_WAVE (SAM_TC0_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC0_DRVCTRL (SAM_TC0_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC0_DBGCTRL (SAM_TC0_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC0_SYNCBUSY (SAM_TC0_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC0_COUNT (SAM_TC0_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC0_COUNT8_PER (SAM_TC0_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC0_COUNT8_CC0 (SAM_TC0_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC0_COUNT8_CC1 (SAM_TC0_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC0_COUNT8_PERBUF (SAM_TC0_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC0_COUNT8_CCBUF0 (SAM_TC0_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC0_COUNT8_CCBUF1 (SAM_TC0_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC0_COUNT16_CC0 (SAM_TC0_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC0_COUNT16_CC1 (SAM_TC0_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC0_COUNT16_CCBUF0 (SAM_TC0_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC0_COUNT16_CCBUF1 (SAM_TC0_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC0_COUNT32_CC0 (SAM_TC0_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC0_COUNT32_CC1 (SAM_TC0_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC0_COUNT32_CCBUF0 (SAM_TC0_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC0_COUNT32_CCBUF1 (SAM_TC0_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
#define SAM_TC1_CTRLA (SAM_TC1_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC1_CTRLBCLR (SAM_TC1_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC1_CTRLBSET (SAM_TC1_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC1_EVCTRL (SAM_TC1_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC1_INTENCLR (SAM_TC1_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC1_INTENSET (SAM_TC1_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC1_INTFLAG (SAM_TC1_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC1_STATUS (SAM_TC1_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC1_WAVE (SAM_TC1_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC1_DRVCTRL (SAM_TC1_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC1_DBGCTRL (SAM_TC1_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC1_SYNCBUSY (SAM_TC1_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC1_COUNT (SAM_TC1_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC1_COUNT8_PER (SAM_TC1_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC1_COUNT8_CC0 (SAM_TC1_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC1_COUNT8_CC1 (SAM_TC1_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC1_COUNT8_PERBUF (SAM_TC1_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC1_COUNT8_CCBUF0 (SAM_TC1_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC1_COUNT8_CCBUF1 (SAM_TC1_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC1_COUNT16_CC0 (SAM_TC1_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC1_COUNT16_CC1 (SAM_TC1_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC1_COUNT16_CCBUF0 (SAM_TC1_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC1_COUNT16_CCBUF1 (SAM_TC1_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC1_COUNT32_CC0 (SAM_TC1_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC1_COUNT32_CC1 (SAM_TC1_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC1_COUNT32_CCBUF0 (SAM_TC1_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC1_COUNT32_CCBUF1 (SAM_TC1_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
#define SAM_TC2_CTRLA (SAM_TC2_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC2_CTRLBCLR (SAM_TC2_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC2_CTRLBSET (SAM_TC2_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC2_EVCTRL (SAM_TC2_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC2_INTENCLR (SAM_TC2_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC2_INTENSET (SAM_TC2_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC2_INTFLAG (SAM_TC2_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC2_STATUS (SAM_TC2_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC2_WAVE (SAM_TC2_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC2_DRVCTRL (SAM_TC2_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC2_DBGCTRL (SAM_TC2_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC2_SYNCBUSY (SAM_TC2_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC2_COUNT (SAM_TC2_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC2_COUNT8_PER (SAM_TC2_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC2_COUNT8_CC0 (SAM_TC2_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC2_COUNT8_CC1 (SAM_TC2_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC2_COUNT8_PERBUF (SAM_TC2_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC2_COUNT8_CCBUF0 (SAM_TC2_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC2_COUNT8_CCBUF1 (SAM_TC2_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC2_COUNT16_CC0 (SAM_TC2_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC2_COUNT16_CC1 (SAM_TC2_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC2_COUNT16_CCBUF0 (SAM_TC2_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC2_COUNT16_CCBUF1 (SAM_TC2_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC2_COUNT32_CC0 (SAM_TC2_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC2_COUNT32_CC1 (SAM_TC2_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC2_COUNT32_CCBUF0 (SAM_TC2_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC2_COUNT32_CCBUF1 (SAM_TC2_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
#define SAM_TC3_CTRLA (SAM_TC3_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC3_CTRLBCLR (SAM_TC3_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC3_CTRLBSET (SAM_TC3_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC3_EVCTRL (SAM_TC3_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC3_INTENCLR (SAM_TC3_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC3_INTENSET (SAM_TC3_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC3_INTFLAG (SAM_TC3_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC3_STATUS (SAM_TC3_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC3_WAVE (SAM_TC3_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC3_DRVCTRL (SAM_TC3_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC3_DBGCTRL (SAM_TC3_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC3_SYNCBUSY (SAM_TC3_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC3_COUNT (SAM_TC3_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC3_COUNT8_PER (SAM_TC3_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC3_COUNT8_CC0 (SAM_TC3_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC3_COUNT8_CC1 (SAM_TC3_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC3_COUNT8_PERBUF (SAM_TC3_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC3_COUNT8_CCBUF0 (SAM_TC3_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC3_COUNT8_CCBUF1 (SAM_TC3_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC3_COUNT16_CC0 (SAM_TC3_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC3_COUNT16_CC1 (SAM_TC3_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC3_COUNT16_CCBUF0 (SAM_TC3_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC3_COUNT16_CCBUF1 (SAM_TC3_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC3_COUNT32_CC0 (SAM_TC3_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC3_COUNT32_CC1 (SAM_TC3_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC3_COUNT32_CCBUF0 (SAM_TC3_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC3_COUNT32_CCBUF1 (SAM_TC3_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
#define SAM_TC4_CTRLA (SAM_TC4_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC4_CTRLBCLR (SAM_TC4_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC4_CTRLBSET (SAM_TC4_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC4_EVCTRL (SAM_TC4_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC4_INTENCLR (SAM_TC4_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC4_INTENSET (SAM_TC4_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC4_INTFLAG (SAM_TC4_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC4_STATUS (SAM_TC4_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC4_WAVE (SAM_TC4_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC4_DRVCTRL (SAM_TC4_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC4_DBGCTRL (SAM_TC4_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC4_SYNCBUSY (SAM_TC4_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC4_COUNT (SAM_TC4_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC4_COUNT8_PER (SAM_TC4_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC4_COUNT8_CC0 (SAM_TC4_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC4_COUNT8_CC1 (SAM_TC4_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC4_COUNT8_PERBUF (SAM_TC4_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC4_COUNT8_CCBUF0 (SAM_TC4_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC4_COUNT8_CCBUF1 (SAM_TC4_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC4_COUNT16_CC0 (SAM_TC4_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC4_COUNT16_CC1 (SAM_TC4_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC4_COUNT16_CCBUF0 (SAM_TC4_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC4_COUNT16_CCBUF1 (SAM_TC4_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC4_COUNT32_CC0 (SAM_TC4_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC4_COUNT32_CC1 (SAM_TC4_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC4_COUNT32_CCBUF0 (SAM_TC4_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC4_COUNT32_CCBUF1 (SAM_TC4_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
#define SAM_TC5_CTRLA (SAM_TC5_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC5_CTRLBCLR (SAM_TC5_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC5_CTRLBSET (SAM_TC5_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC5_EVCTRL (SAM_TC5_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC5_INTENCLR (SAM_TC5_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC5_INTENSET (SAM_TC5_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC5_INTFLAG (SAM_TC5_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC5_STATUS (SAM_TC5_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC5_WAVE (SAM_TC5_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC5_DRVCTRL (SAM_TC5_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC5_DBGCTRL (SAM_TC5_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC5_SYNCBUSY (SAM_TC5_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC5_COUNT (SAM_TC5_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC5_COUNT8_PER (SAM_TC5_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC5_COUNT8_CC0 (SAM_TC5_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC5_COUNT8_CC1 (SAM_TC5_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC5_COUNT8_PERBUF (SAM_TC5_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC5_COUNT8_CCBUF0 (SAM_TC5_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC5_COUNT8_CCBUF1 (SAM_TC5_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC5_COUNT16_CC0 (SAM_TC5_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC5_COUNT16_CC1 (SAM_TC5_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC5_COUNT16_CCBUF0 (SAM_TC5_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC5_COUNT16_CCBUF1 (SAM_TC5_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC5_COUNT32_CC0 (SAM_TC5_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC5_COUNT32_CC1 (SAM_TC5_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC5_COUNT32_CCBUF0 (SAM_TC5_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC5_COUNT32_CCBUF1 (SAM_TC5_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
/****************************************************************************
|
||||
* Not used
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
#define SAM_TC6_CTRLA (SAM_TC6_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC6_CTRLBCLR (SAM_TC6_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC6_CTRLBSET (SAM_TC6_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC6_EVCTRL (SAM_TC6_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC6_INTENCLR (SAM_TC6_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC6_INTENSET (SAM_TC6_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC6_INTFLAG (SAM_TC6_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC6_STATUS (SAM_TC6_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC6_WAVE (SAM_TC6_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC6_DRVCTRL (SAM_TC6_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC6_DBGCTRL (SAM_TC6_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC6_SYNCBUSY (SAM_TC6_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC6_COUNT (SAM_TC6_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC6_COUNT8_PER (SAM_TC6_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC6_COUNT8_CC0 (SAM_TC6_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC6_COUNT8_CC1 (SAM_TC6_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC6_COUNT8_PERBUF (SAM_TC6_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC6_COUNT8_CCBUF0 (SAM_TC6_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC6_COUNT8_CCBUF1 (SAM_TC6_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC6_COUNT16_CC0 (SAM_TC6_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC6_COUNT16_CC1 (SAM_TC6_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC6_COUNT16_CCBUF0 (SAM_TC6_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC6_COUNT16_CCBUF1 (SAM_TC6_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC6_COUNT32_CC0 (SAM_TC6_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC6_COUNT32_CC1 (SAM_TC6_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC6_COUNT32_CCBUF0 (SAM_TC6_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC6_COUNT32_CCBUF1 (SAM_TC6_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
#define SAM_TC7_CTRLA (SAM_TC7_BASE+SAM_TC_CTRLA_OFFSET)
|
||||
#define SAM_TC7_CTRLBCLR (SAM_TC7_BASE+SAM_TC_CTRLBCLR_OFFSET)
|
||||
#define SAM_TC7_CTRLBSET (SAM_TC7_BASE+SAM_TC_CTRLBSET_OFFSET)
|
||||
#define SAM_TC7_EVCTRL (SAM_TC7_BASE+SAM_TC_EVCTRL_OFFSET)
|
||||
#define SAM_TC7_INTENCLR (SAM_TC7_BASE+SAM_TC_INTENCLR_OFFSET)
|
||||
#define SAM_TC7_INTENSET (SAM_TC7_BASE+SAM_TC_INTENSET_OFFSET)
|
||||
#define SAM_TC7_INTFLAG (SAM_TC7_BASE+SAM_TC_INTFLAG_OFFSET)
|
||||
#define SAM_TC7_STATUS (SAM_TC7_BASE+SAM_TC_STATUS_OFFSET)
|
||||
#define SAM_TC7_WAVE (SAM_TC7_BASE+SAM_TC_WAVE_OFFSET)
|
||||
#define SAM_TC7_DRVCTRL (SAM_TC7_BASE+SAM_TC_DRVCTRL_OFFSET)
|
||||
#define SAM_TC7_DBGCTRL (SAM_TC7_BASE+SAM_TC_DBGCTRL_OFFSET)
|
||||
#define SAM_TC7_SYNCBUSY (SAM_TC7_BASE+SAM_TC_SYNCBUSY_OFFSET)
|
||||
#define SAM_TC7_COUNT (SAM_TC7_BASE+SAM_TC_COUNT_OFFSET)
|
||||
#define SAM_TC7_COUNT8_PER (SAM_TC7_BASE+SAM_TC_COUNT8_PER_OFFSET)
|
||||
#define SAM_TC7_COUNT8_CC0 (SAM_TC7_BASE+SAM_TC_COUNT8_CC0_OFFSET)
|
||||
#define SAM_TC7_COUNT8_CC1 (SAM_TC7_BASE+SAM_TC_COUNT8_CC1_OFFSET)
|
||||
#define SAM_TC7_COUNT8_PERBUF (SAM_TC7_BASE+SAM_TC_COUNT8_PERBUF_OFFSET)
|
||||
#define SAM_TC7_COUNT8_CCBUF0 (SAM_TC7_BASE+SAM_TC_COUNT8_CCBUF0_OFFSET)
|
||||
#define SAM_TC7_COUNT8_CCBUF1 (SAM_TC7_BASE+SAM_TC_COUNT8_CCBUF1_OFFSET)
|
||||
#define SAM_TC7_COUNT16_CC0 (SAM_TC7_BASE+SAM_TC_COUNT16_CC0_OFFSET)
|
||||
#define SAM_TC7_COUNT16_CC1 (SAM_TC7_BASE+SAM_TC_COUNT16_CC1_OFFSET)
|
||||
#define SAM_TC7_COUNT16_CCBUF0 (SAM_TC7_BASE+SAM_TC_COUNT16_CCBUF0_OFFSET)
|
||||
#define SAM_TC7_COUNT16_CCBUF1 (SAM_TC7_BASE+SAM_TC_COUNT16_CCBUF1_OFFSET)
|
||||
#define SAM_TC7_COUNT32_CC0 (SAM_TC7_BASE+SAM_TC_COUNT32_CC0_OFFSET)
|
||||
#define SAM_TC7_COUNT32_CC1 (SAM_TC7_BASE+SAM_TC_COUNT32_CC1_OFFSET)
|
||||
#define SAM_TC7_COUNT32_CCBUF0 (SAM_TC7_BASE+SAM_TC_COUNT32_CCBUF0_OFFSET)
|
||||
#define SAM_TC7_COUNT32_CCBUF1 (SAM_TC7_BASE+SAM_TC_COUNT32_CCBUF1_OFFSET)
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
/* TC register bit definitions */
|
||||
|
||||
/* Control A register */
|
||||
|
||||
#define TC_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */
|
||||
#define TC_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */
|
||||
#define TC_CTRLA_DISABLE (0 << 1) /* Bit 1: Disable */
|
||||
#define TC_CTRLA_MODE_SHIFT (2)
|
||||
#define TC_CTRLA_MODE_MASK (3 << TC_CTRLA_MODE_SHIFT)
|
||||
#define TC_CTRLA_MODE_COUNT16 (0 << TC_CTRLA_MODE_SHIFT)
|
||||
#define TC_CTRLA_MODE_COUNT8 (1 << TC_CTRLA_MODE_SHIFT)
|
||||
#define TC_CTRLA_MODE_COUNT32 (2 << TC_CTRLA_MODE_SHIFT)
|
||||
#define TC_CTRLA_PRESCSYNC_SHIFT (4)
|
||||
#define TC_CTRLA_PRESCSYNC_MASK (3 << TC_CTRLA_PRESCSYNC_SHIFT)
|
||||
#define TC_CTRLA_PRESCSYNC_GCLK (0 << TC_CTRLA_PRESCSYNC_SHIFT)
|
||||
#define TC_CTRLA_PRESCSYNC_PRESC (1 << TC_CTRLA_PRESCSYNC_SHIFT)
|
||||
#define TC_CTRLA_PRESCSYNC_RESYNC (2 << TC_CTRLA_PRESCSYNC_SHIFT)
|
||||
#define TC_CTRLA_RUNSTDBY (1 << 6)
|
||||
#define TC_CTRLA_ONDEMAND (1 << 7)
|
||||
#define TC_CTRLA_PRESCALER_SHIFT (8)
|
||||
#define TC_CTRLA_PRESCALER_MASK (7 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER(n) ((uint32_t)(n) << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV1 (0 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV2 (1 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV4 (2 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV8 (3 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV16 (4 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV64 (5 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV256 (6 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_PRESCALER_DIV1024 (7 << TC_CTRLA_PRESCALER_SHIFT)
|
||||
#define TC_CTRLA_ALOCK (1 << 11)
|
||||
#define TC_CTRLA_CAPTEN0_SHIFT (16) /* (TC_CTRLA) Capture Channel 0 Enable */
|
||||
#define TC_CTRLA_CAPTEN0 (1 << TC_CTRLA_CAPTEN0_SHIFT)
|
||||
#define TC_CTRLA_CAPTEN1_SHIFT (17) /* (TC_CTRLA) Capture Channel 1 Enable */
|
||||
#define TC_CTRLA_CAPTEN1 (1 << TC_CTRLA_CAPTEN1_SHIFT)
|
||||
#define TC_CTRLA_COPEN0_SHIFT (20) /* (TC_CTRLA) Capture On Pin 0 Enable */
|
||||
#define TC_CTRLA_COPEN0 (1 << TC_CTRLA_COPEN1_SHIFT)
|
||||
#define TC_CTRLA_COPEN1_SHIFT (21) /* (TC_CTRLA) Capture On Pin 1 Enable */
|
||||
#define TC_CTRLA_COPEN1 (1 << TC_CTRLA_CAPTEN1_SHIFT)
|
||||
#define TC_CTRLA_CAPTMODE0_SHIFT (24) /* (TC_CTRLA) Capture Mode Channel 0 */
|
||||
#define TC_CTRLA_CAPTMODE0_MASK (3 << TC_CTRLA_CAPTMODE0_SHIFT)
|
||||
#define TC_CTRLA_CAPTMODE0_CAPTD (0 << TC_CTRLA_CAPTMODE0_SHIFT) /* (TC_CTRLA) Default capture */
|
||||
#define TC_CTRLA_CAPTMODE0_CAPTMIN (1 << TC_CTRLA_CAPTMODE0_SHIFT) /* (TC_CTRLA) Minimum capture */
|
||||
#define TC_CTRLA_CAPTMODE0_CAPTMAX (2 << TC_CTRLA_CAPTMODE0_SHIFT) /* (TC_CTRLA) Maximum capture */
|
||||
#define TC_CTRLA_CAPTMODE1_SHIFT (27) /* (TC_CTRLA) Capture Mode Channel 0 */
|
||||
#define TC_CTRLA_CAPTMODE1_MASK (3 << TC_CTRLA_CAPTMODE1_SHIFT)
|
||||
#define TC_CTRLA_CAPTMODE1_CAPTD (0 << TC_CTRLA_CAPTMODE1_SHIFT) /* (TC_CTRLA) Default capture */
|
||||
#define TC_CTRLA_CAPTMODE1_CAPTMIN (1 << TC_CTRLA_CAPTMODE1_SHIFT) /* (TC_CTRLA) Minimum capture */
|
||||
#define TC_CTRLA_CAPTMODE1_CAPTMAX (2 << TC_CTRLA_CAPTMODE1_SHIFT) /* (TC_CTRLA) Maximum capture */
|
||||
|
||||
/* Control B Clear register */
|
||||
|
||||
#define TC_CTRLBCLR_DIR (1 << 0)
|
||||
#define TC_CTRLBCLR_LUPD (1 << 1)
|
||||
#define TC_CTRLBCLR_ONESHOT (1 << 2)
|
||||
#define TC_CTRLBCLR_CMD_SHIFT (5)
|
||||
#define TC_CTRLBCLR_CMD_MASK (7 << TC_CTRLBCLR_CMD_SHIFT)
|
||||
#define TC_CTRLBCLR_CMD_NONE (0 << TC_CTRLBCLR_CMD_SHIFT) /* (TC_CTRLBCLR) No action */
|
||||
#define TC_CTRLBCLR_CMD_RETRIGGER (1 << TC_CTRLBCLR_CMD_SHIFT) /* (TC_CTRLBCLR) Force a start, restart or retrigger */
|
||||
#define TC_CTRLBCLR_CMD_STOP (2 << TC_CTRLBCLR_CMD_SHIFT) /* (TC_CTRLBCLR) Force a stop */
|
||||
#define TC_CTRLBCLR_CMD_UPDATE (3 << TC_CTRLBCLR_CMD_SHIFT) /* (TC_CTRLBCLR) Force update of double-buffered register */
|
||||
#define TC_CTRLBCLR_CMD_READSYNC (4 << TC_CTRLBCLR_CMD_SHIFT) /* (TC_CTRLBCLR) Force a read synchronization of COUNT */
|
||||
#define TC_CTRLBCLR_CMD_DMAOS (5 << TC_CTRLBCLR_CMD_SHIFT) /* (TC_CTRLBCLR) One-shot DMA trigger */
|
||||
|
||||
/* Control B Set register */
|
||||
|
||||
#define TC_CTRLBSET_DIR (1 << 0)
|
||||
#define TC_CTRLBSET_LUPD (1 << 1)
|
||||
#define TC_CTRLBSET_ONESHOT (1 << 2)
|
||||
#define TC_CTRLBSET_CMD_SHIFT (5)
|
||||
#define TC_CTRLBSET_CMD_MASK (7 << TC_CTRLBSET_CMD_SHIFT)
|
||||
#define TC_CTRLBSET_CMD_NONE (0 << TC_CTRLBSET_CMD_SHIFT) /* (TC_CTRLBCLR) No action */
|
||||
#define TC_CTRLBSET_CMD_RETRIGGER (1 << TC_CTRLBSET_CMD_SHIFT) /* (TC_CTRLBCLR) Force a start, restart or retrigger */
|
||||
#define TC_CTRLBSET_CMD_STOP (2 << TC_CTRLBSET_CMD_SHIFT) /* (TC_CTRLBCLR) Force a stop */
|
||||
#define TC_CTRLBSET_CMD_UPDATE (3 << TC_CTRLBSET_CMD_SHIFT) /* (TC_CTRLBCLR) Force update of double-buffered register */
|
||||
#define TC_CTRLBSET_CMD_READSYNC (4 << TC_CTRLBSET_CMD_SHIFT) /* (TC_CTRLBCLR) Force a read synchronization of COUNT */
|
||||
#define TC_CTRLBSET_CMD_DMAOS (5 << TC_CTRLBSET_CMD_SHIFT) /* (TC_CTRLBCLR) One-shot DMA trigger */
|
||||
|
||||
/* Event control register */
|
||||
|
||||
#define TC_EVCTRL_EVACT_SHIFT (0)
|
||||
#define TC_EVCTRL_EVACT_MASK (7 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_OFF (0 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_RETRIGGER (1 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_COUNT (2 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_START (3 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_STAMP (4 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_PPW (5 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_PWP (6 << TC_EVCTRL_EVACT_SHIFT)
|
||||
# define TC_EVCTRL_EVACT_PW (7 << TC_EVCTRL_EVACT_SHIFT)
|
||||
#define TC_EVCTRL_TCINV (1 << 4)
|
||||
#define TC_EVCTRL_TCEI (1 << 5)
|
||||
#define TC_EVCTRL_OVFEO (1 << 8)
|
||||
#define TC_EVCTRL_MCEO0 (1 << 12)
|
||||
#define TC_EVCTRL_MCEO1 (1 << 13)
|
||||
|
||||
/* TC_INTENCLR : Interrupt Enable Clear */
|
||||
|
||||
#define TC_INTENCLR_OVF (1 << 0) /* (TC_INTENCLR) OVF Interrupt Disable */
|
||||
#define TC_INTENCLR_ERR (1 << 1) /* (TC_INTENCLR) ERR Interrupt Disable */
|
||||
#define TC_INTENCLR_MC0 (1 << 4) /* (TC_INTENCLR) MC Interrupt Disable 0 */
|
||||
#define TC_INTENCLR_MC1 (1 << 5) /* (TC_INTENCLR) MC Interrupt Disable 1 */
|
||||
|
||||
/* TC_INTENSET : Interrupt Enable Set */
|
||||
|
||||
#define TC_INTENSET_OVF (1 << 0) /* (TC_INTENCLR) OVF Interrupt Disable */
|
||||
#define TC_INTENSET_ERR (1 << 1) /* (TC_INTENCLR) ERR Interrupt Disable */
|
||||
#define TC_INTENSET_MC0 (1 << 4) /* (TC_INTENCLR) MC Interrupt Disable 0 */
|
||||
#define TC_INTENSET_MC1 (1 << 5) /* (TC_INTENCLR) MC Interrupt Disable 1 */
|
||||
|
||||
/* TC_INTFLAG : Interrupt Flag Status and Clear */
|
||||
|
||||
#define TC_INTFLAG_OVF (1 << 0) /* (TC_INTENCLR) OVF Interrupt Disable */
|
||||
#define TC_INTFLAG_ERR (1 << 1) /* (TC_INTENCLR) ERR Interrupt Disable */
|
||||
#define TC_INTFLAG_MC0 (1 << 4) /* (TC_INTENCLR) MC Interrupt Disable 0 */
|
||||
#define TC_INTFLAG_MC1 (1 << 5) /* (TC_INTENCLR) MC Interrupt Disable 1 */
|
||||
#define TC_INTFLAG_ALL (TC_INTFLAG_OVF | TC_INTFLAG_ERR | TC_INTFLAG_MC0 | TC_INTFLAG_MC1)
|
||||
|
||||
/* Status register */
|
||||
|
||||
#define TC_STATUS_STOP (1 << 0)
|
||||
#define TC_STATUS_SLAVE (1 << 1)
|
||||
#define TC_STATUS_PERBUFV (1 << 3)
|
||||
#define TC_STATUS_CCBUFV0 (1 << 4)
|
||||
#define TC_STATUS_CCBUFV1 (1 << 5)
|
||||
|
||||
/* TC_WAVE : Waveform Generation Control */
|
||||
|
||||
#define TC_WAVE_WAVEGEN_SHIFT (0) /* (TC_WAVE) Waveform Generation Mode */
|
||||
#define TC_WAVE_WAVEGEN_Msk (3 << TC_WAVE_WAVEGEN_SHIFT)
|
||||
|
||||
#define TC_WAVE_WAVEGEN_NFRQ (0 << TC_WAVE_WAVEGEN_SHIFT) /* (TC_WAVE) Normal frequency */
|
||||
#define TC_WAVE_WAVEGEN_MFRQ (1 << TC_WAVE_WAVEGEN_SHIFT) /* (TC_WAVE) Match frequency */
|
||||
#define TC_WAVE_WAVEGEN_NPWM (2 << TC_WAVE_WAVEGEN_SHIFT) /* (TC_WAVE) Normal PWM */
|
||||
#define TC_WAVE_WAVEGEN_MPWM (3 << TC_WAVE_WAVEGEN_SHIFT) /* (TC_WAVE) Match PWM */
|
||||
|
||||
/* TC_DRVCTRL : Control C */
|
||||
|
||||
#define TC_DRVCTRL_INVEN0 (1 << 0 /* (TC_DRVCTRL) Output Waveform Invert Enable 0 */
|
||||
#define TC_DRVCTRL_INVEN1 (1 << 1) /* (TC_DRVCTRL) Output Waveform Invert Enable 1 */
|
||||
|
||||
/* TC_DBGCTRL : Debug Control */
|
||||
|
||||
#define TC_DBGCTRL_DBGRUN (1 << 0) /* (TC_DBGCTRL) Run During Debug */
|
||||
|
||||
/* TC_SYNCBUSY : Synchronization Status */
|
||||
|
||||
#define TC_SYNCBUSY_SWRST (1 << 0) /* (TC_SYNCBUSY) swrst */
|
||||
#define TC_SYNCBUSY_ENABLE (1 << 1) /* (TC_SYNCBUSY) enable */
|
||||
#define TC_SYNCBUSY_CTRLB (1 << 2) /* (TC_SYNCBUSY) CTRLB */
|
||||
#define TC_SYNCBUSY_STATUS (1 << 3) /* (TC_SYNCBUSY) STATUS */
|
||||
#define TC_SYNCBUSY_COUNT (1 << 4) /* (TC_SYNCBUSY) Counter */
|
||||
#define TC_SYNCBUSY_CC0 (1 << 6) /* (TC_SYNCBUSY) Compare Channel 0 */
|
||||
#define TC_SYNCBUSY_CC1 (1 << 7) /* (TC_SYNCBUSY) Compare Channel 1 */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_SAMD5E5_CHIP_SAMD_TC_H */
|
@ -82,209 +82,209 @@ static const struct sam_clockconfig_s g_initial_clocking =
|
||||
.gclkset2 = BOARD_GCLK_SET2,
|
||||
.cpu_frequency = BOARD_CPU_FREQUENCY,
|
||||
#if BOARD_HAVE_XOSC32K != 0
|
||||
.xosc32k =
|
||||
{
|
||||
.enable = BOARD_XOSC32K_ENABLE,
|
||||
.highspeed = BOARD_XOSC32K_HIGHSPEED,
|
||||
.extalen = BOARD_XOSC32K_XTALEN,
|
||||
.en32k = BOARD_XOSC32K_EN32K,
|
||||
.en1k = BOARD_XOSC32K_EN1K,
|
||||
.runstdby = BOARD_XOSC32K_RUNSTDBY,
|
||||
.ondemand = BOARD_XOSC32K_ONDEMAND,
|
||||
.cfden = BOARD_XOSC32K_CFDEN,
|
||||
.cfdeo = BOARD_XOSC32K_CFDEO,
|
||||
.caliben = BOARD_XOSC32K_CALIBEN,
|
||||
.startup = BOARD_XOSC32K_STARTUP,
|
||||
.calib = BOARD_XOSC32K_CALIB,
|
||||
.rtcsel = BOARD_XOSC32K_RTCSEL,
|
||||
},
|
||||
.xosc32k =
|
||||
{
|
||||
.enable = BOARD_XOSC32K_ENABLE,
|
||||
.highspeed = BOARD_XOSC32K_HIGHSPEED,
|
||||
.extalen = BOARD_XOSC32K_XTALEN,
|
||||
.en32k = BOARD_XOSC32K_EN32K,
|
||||
.en1k = BOARD_XOSC32K_EN1K,
|
||||
.runstdby = BOARD_XOSC32K_RUNSTDBY,
|
||||
.ondemand = BOARD_XOSC32K_ONDEMAND,
|
||||
.cfden = BOARD_XOSC32K_CFDEN,
|
||||
.cfdeo = BOARD_XOSC32K_CFDEO,
|
||||
.caliben = BOARD_XOSC32K_CALIBEN,
|
||||
.startup = BOARD_XOSC32K_STARTUP,
|
||||
.calib = BOARD_XOSC32K_CALIB,
|
||||
.rtcsel = BOARD_XOSC32K_RTCSEL,
|
||||
},
|
||||
#endif
|
||||
#if BOARD_HAVE_XOSC0 != 0
|
||||
.xosc0 =
|
||||
{
|
||||
.enable = BOARD_XOSC0_ENABLE,
|
||||
.extalen = BOARD_XOSC0_XTALEN,
|
||||
.runstdby = BOARD_XOSC0_RUNSTDBY,
|
||||
.ondemand = BOARD_XOSC0_ONDEMAND,
|
||||
.lowgain = BOARD_XOSC0_LOWGAIN,
|
||||
.enalc = BOARD_XOSC0_ENALC,
|
||||
.cfden = BOARD_XOSC0_CFDEN,
|
||||
.startup = BOARD_XOSC0_STARTUP,
|
||||
.xosc_frequency = BOARD_XOSC0_FREQUENCY,
|
||||
},
|
||||
.xosc0 =
|
||||
{
|
||||
.enable = BOARD_XOSC0_ENABLE,
|
||||
.extalen = BOARD_XOSC0_XTALEN,
|
||||
.runstdby = BOARD_XOSC0_RUNSTDBY,
|
||||
.ondemand = BOARD_XOSC0_ONDEMAND,
|
||||
.lowgain = BOARD_XOSC0_LOWGAIN,
|
||||
.enalc = BOARD_XOSC0_ENALC,
|
||||
.cfden = BOARD_XOSC0_CFDEN,
|
||||
.startup = BOARD_XOSC0_STARTUP,
|
||||
.xosc_frequency = BOARD_XOSC0_FREQUENCY,
|
||||
},
|
||||
#endif
|
||||
#if BOARD_HAVE_XOSC1 != 0
|
||||
.xosc1 =
|
||||
{
|
||||
.enable = BOARD_XOSC1_ENABLE,
|
||||
.extalen = BOARD_XOSC1_XTALEN,
|
||||
.runstdby = BOARD_XOSC1_RUNSTDBY,
|
||||
.ondemand = BOARD_XOSC1_ONDEMAND,
|
||||
.lowgain = BOARD_XOSC1_LOWGAIN,
|
||||
.enalc = BOARD_XOSC1_ENALC,
|
||||
.cfden = BOARD_XOSC1_CFDEN,
|
||||
.startup = BOARD_XOSC1_STARTUP,
|
||||
.xosc_frequency = BOARD_XOSC1_FREQUENCY,
|
||||
},
|
||||
.xosc1 =
|
||||
{
|
||||
.enable = BOARD_XOSC1_ENABLE,
|
||||
.extalen = BOARD_XOSC1_XTALEN,
|
||||
.runstdby = BOARD_XOSC1_RUNSTDBY,
|
||||
.ondemand = BOARD_XOSC1_ONDEMAND,
|
||||
.lowgain = BOARD_XOSC1_LOWGAIN,
|
||||
.enalc = BOARD_XOSC1_ENALC,
|
||||
.cfden = BOARD_XOSC1_CFDEN,
|
||||
.startup = BOARD_XOSC1_STARTUP,
|
||||
.xosc_frequency = BOARD_XOSC1_FREQUENCY,
|
||||
},
|
||||
#endif
|
||||
.dfll =
|
||||
{
|
||||
.enable = BOARD_DFLL_ENABLE,
|
||||
.runstdby = BOARD_DFLL_RUNSTDBY,
|
||||
.ondemand = BOARD_DFLL_ONDEMAND,
|
||||
.mode = BOARD_DFLL_MODE,
|
||||
.stable = BOARD_DFLL_STABLE,
|
||||
.llaw = BOARD_DFLL_LLAW,
|
||||
.usbcrm = BOARD_DFLL_USBCRM,
|
||||
.ccdis = BOARD_DFLL_CCDIS,
|
||||
.qldis = BOARD_DFLL_QLDIS,
|
||||
.bplckc = BOARD_DFLL_BPLCKC,
|
||||
.waitlock = BOARD_DFLL_WAITLOCK,
|
||||
.caliben = BOARD_DFLL_CALIBEN,
|
||||
.gclklock = BOARD_DFLL_GCLKLOCK,
|
||||
.fcalib = BOARD_DFLL_FCALIB,
|
||||
.ccalib = BOARD_DFLL_CCALIB,
|
||||
.fstep = BOARD_DFLL_FSTEP,
|
||||
.cstep = BOARD_DFLL_CSTEP,
|
||||
.gclk = BOARD_DFLL_GCLK,
|
||||
.mul = BOARD_DFLL_MUL
|
||||
},
|
||||
.dpll =
|
||||
{
|
||||
{
|
||||
.enable = BOARD_DPLL0_ENABLE,
|
||||
.dcoen = BOARD_DPLL0_DCOEN,
|
||||
.lbypass = BOARD_DPLL0_LBYPASS,
|
||||
.wuf = BOARD_DPLL0_WUF,
|
||||
.runstdby = BOARD_DPLL0_RUNSTDBY,
|
||||
.ondemand = BOARD_DPLL0_ONDEMAND,
|
||||
.reflock = BOARD_DPLL0_REFLOCK,
|
||||
.refclk = BOARD_DPLL0_REFCLK,
|
||||
.ltime = BOARD_DPLL0_LTIME,
|
||||
.filter = BOARD_DPLL0_FILTER,
|
||||
.dcofilter = BOARD_DPLL0_DCOFILTER,
|
||||
.gclk = BOARD_DPLL0_GCLK,
|
||||
.ldrfrac = BOARD_DPLL0_LDRFRAC,
|
||||
.ldrint = BOARD_DPLL0_LDRINT,
|
||||
.div = BOARD_DPLL0_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_DPLL1_ENABLE,
|
||||
.dcoen = BOARD_DPLL1_DCOEN,
|
||||
.lbypass = BOARD_DPLL1_LBYPASS,
|
||||
.wuf = BOARD_DPLL1_WUF,
|
||||
.runstdby = BOARD_DPLL1_RUNSTDBY,
|
||||
.ondemand = BOARD_DPLL1_ONDEMAND,
|
||||
.reflock = BOARD_DPLL1_REFLOCK,
|
||||
.refclk = BOARD_DPLL1_REFCLK,
|
||||
.ltime = BOARD_DPLL1_LTIME,
|
||||
.filter = BOARD_DPLL1_FILTER,
|
||||
.dcofilter = BOARD_DPLL1_DCOFILTER,
|
||||
.gclk = BOARD_DPLL1_GCLK,
|
||||
.ldrfrac = BOARD_DPLL1_LDRFRAC,
|
||||
.ldrint = BOARD_DPLL1_LDRINT,
|
||||
.div = BOARD_DPLL1_DIV
|
||||
}
|
||||
},
|
||||
.gclk =
|
||||
{
|
||||
{
|
||||
.enable = BOARD_GCLK0_ENABLE,
|
||||
.oov = BOARD_GCLK0_OOV,
|
||||
.oe = BOARD_GCLK0_OE,
|
||||
.runstdby = BOARD_GCLK0_RUNSTDBY,
|
||||
.source = BOARD_GCLK0_SOURCE,
|
||||
.div = BOARD_GCLK0_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK1_ENABLE,
|
||||
.oov = BOARD_GCLK1_OOV,
|
||||
.oe = BOARD_GCLK1_OE,
|
||||
.runstdby = BOARD_GCLK1_RUNSTDBY,
|
||||
.source = BOARD_GCLK1_SOURCE,
|
||||
.div = BOARD_GCLK1_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK2_ENABLE,
|
||||
.oov = BOARD_GCLK2_OOV,
|
||||
.oe = BOARD_GCLK2_OE,
|
||||
.runstdby = BOARD_GCLK2_RUNSTDBY,
|
||||
.source = BOARD_GCLK2_SOURCE,
|
||||
.div = BOARD_GCLK2_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK3_ENABLE,
|
||||
.oov = BOARD_GCLK3_OOV,
|
||||
.oe = BOARD_GCLK3_OE,
|
||||
.runstdby = BOARD_GCLK3_RUNSTDBY,
|
||||
.source = BOARD_GCLK3_SOURCE,
|
||||
.div = BOARD_GCLK3_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK4_ENABLE,
|
||||
.oov = BOARD_GCLK4_OOV,
|
||||
.oe = BOARD_GCLK4_OE,
|
||||
.runstdby = BOARD_GCLK4_RUNSTDBY,
|
||||
.source = BOARD_GCLK4_SOURCE,
|
||||
.div = BOARD_GCLK4_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK5_ENABLE,
|
||||
.oov = BOARD_GCLK5_OOV,
|
||||
.oe = BOARD_GCLK5_OE,
|
||||
.runstdby = BOARD_GCLK5_RUNSTDBY,
|
||||
.source = BOARD_GCLK5_SOURCE,
|
||||
.div = BOARD_GCLK5_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK6_ENABLE,
|
||||
.oov = BOARD_GCLK6_OOV,
|
||||
.oe = BOARD_GCLK6_OE,
|
||||
.runstdby = BOARD_GCLK6_RUNSTDBY,
|
||||
.source = BOARD_GCLK6_SOURCE,
|
||||
.div = BOARD_GCLK6_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK7_ENABLE,
|
||||
.oov = BOARD_GCLK7_OOV,
|
||||
.oe = BOARD_GCLK7_OE,
|
||||
.runstdby = BOARD_GCLK7_RUNSTDBY,
|
||||
.source = BOARD_GCLK7_SOURCE,
|
||||
.div = BOARD_GCLK7_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK8_ENABLE,
|
||||
.oov = BOARD_GCLK8_OOV,
|
||||
.oe = BOARD_GCLK8_OE,
|
||||
.runstdby = BOARD_GCLK8_RUNSTDBY,
|
||||
.source = BOARD_GCLK8_SOURCE,
|
||||
.div = BOARD_GCLK8_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK9_ENABLE,
|
||||
.oov = BOARD_GCLK9_OOV,
|
||||
.oe = BOARD_GCLK9_OE,
|
||||
.runstdby = BOARD_GCLK9_RUNSTDBY,
|
||||
.source = BOARD_GCLK9_SOURCE,
|
||||
.div = BOARD_GCLK9_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK10_ENABLE,
|
||||
.oov = BOARD_GCLK10_OOV,
|
||||
.oe = BOARD_GCLK10_OE,
|
||||
.runstdby = BOARD_GCLK10_RUNSTDBY,
|
||||
.source = BOARD_GCLK10_SOURCE,
|
||||
.div = BOARD_GCLK10_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK11_ENABLE,
|
||||
.oov = BOARD_GCLK11_OOV,
|
||||
.oe = BOARD_GCLK11_OE,
|
||||
.runstdby = BOARD_GCLK11_RUNSTDBY,
|
||||
.source = BOARD_GCLK11_SOURCE,
|
||||
.div = BOARD_GCLK11_DIV
|
||||
}
|
||||
}
|
||||
.dfll =
|
||||
{
|
||||
.enable = BOARD_DFLL_ENABLE,
|
||||
.runstdby = BOARD_DFLL_RUNSTDBY,
|
||||
.ondemand = BOARD_DFLL_ONDEMAND,
|
||||
.mode = BOARD_DFLL_MODE,
|
||||
.stable = BOARD_DFLL_STABLE,
|
||||
.llaw = BOARD_DFLL_LLAW,
|
||||
.usbcrm = BOARD_DFLL_USBCRM,
|
||||
.ccdis = BOARD_DFLL_CCDIS,
|
||||
.qldis = BOARD_DFLL_QLDIS,
|
||||
.bplckc = BOARD_DFLL_BPLCKC,
|
||||
.waitlock = BOARD_DFLL_WAITLOCK,
|
||||
.caliben = BOARD_DFLL_CALIBEN,
|
||||
.gclklock = BOARD_DFLL_GCLKLOCK,
|
||||
.fcalib = BOARD_DFLL_FCALIB,
|
||||
.ccalib = BOARD_DFLL_CCALIB,
|
||||
.fstep = BOARD_DFLL_FSTEP,
|
||||
.cstep = BOARD_DFLL_CSTEP,
|
||||
.gclk = BOARD_DFLL_GCLK,
|
||||
.mul = BOARD_DFLL_MUL
|
||||
},
|
||||
.dpll =
|
||||
{
|
||||
{
|
||||
.enable = BOARD_DPLL0_ENABLE,
|
||||
.dcoen = BOARD_DPLL0_DCOEN,
|
||||
.lbypass = BOARD_DPLL0_LBYPASS,
|
||||
.wuf = BOARD_DPLL0_WUF,
|
||||
.runstdby = BOARD_DPLL0_RUNSTDBY,
|
||||
.ondemand = BOARD_DPLL0_ONDEMAND,
|
||||
.reflock = BOARD_DPLL0_REFLOCK,
|
||||
.refclk = BOARD_DPLL0_REFCLK,
|
||||
.ltime = BOARD_DPLL0_LTIME,
|
||||
.filter = BOARD_DPLL0_FILTER,
|
||||
.dcofilter = BOARD_DPLL0_DCOFILTER,
|
||||
.gclk = BOARD_DPLL0_GCLK,
|
||||
.ldrfrac = BOARD_DPLL0_LDRFRAC,
|
||||
.ldrint = BOARD_DPLL0_LDRINT,
|
||||
.div = BOARD_DPLL0_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_DPLL1_ENABLE,
|
||||
.dcoen = BOARD_DPLL1_DCOEN,
|
||||
.lbypass = BOARD_DPLL1_LBYPASS,
|
||||
.wuf = BOARD_DPLL1_WUF,
|
||||
.runstdby = BOARD_DPLL1_RUNSTDBY,
|
||||
.ondemand = BOARD_DPLL1_ONDEMAND,
|
||||
.reflock = BOARD_DPLL1_REFLOCK,
|
||||
.refclk = BOARD_DPLL1_REFCLK,
|
||||
.ltime = BOARD_DPLL1_LTIME,
|
||||
.filter = BOARD_DPLL1_FILTER,
|
||||
.dcofilter = BOARD_DPLL1_DCOFILTER,
|
||||
.gclk = BOARD_DPLL1_GCLK,
|
||||
.ldrfrac = BOARD_DPLL1_LDRFRAC,
|
||||
.ldrint = BOARD_DPLL1_LDRINT,
|
||||
.div = BOARD_DPLL1_DIV
|
||||
}
|
||||
},
|
||||
.gclk =
|
||||
{
|
||||
{
|
||||
.enable = BOARD_GCLK0_ENABLE,
|
||||
.oov = BOARD_GCLK0_OOV,
|
||||
.oe = BOARD_GCLK0_OE,
|
||||
.runstdby = BOARD_GCLK0_RUNSTDBY,
|
||||
.source = BOARD_GCLK0_SOURCE,
|
||||
.div = BOARD_GCLK0_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK1_ENABLE,
|
||||
.oov = BOARD_GCLK1_OOV,
|
||||
.oe = BOARD_GCLK1_OE,
|
||||
.runstdby = BOARD_GCLK1_RUNSTDBY,
|
||||
.source = BOARD_GCLK1_SOURCE,
|
||||
.div = BOARD_GCLK1_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK2_ENABLE,
|
||||
.oov = BOARD_GCLK2_OOV,
|
||||
.oe = BOARD_GCLK2_OE,
|
||||
.runstdby = BOARD_GCLK2_RUNSTDBY,
|
||||
.source = BOARD_GCLK2_SOURCE,
|
||||
.div = BOARD_GCLK2_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK3_ENABLE,
|
||||
.oov = BOARD_GCLK3_OOV,
|
||||
.oe = BOARD_GCLK3_OE,
|
||||
.runstdby = BOARD_GCLK3_RUNSTDBY,
|
||||
.source = BOARD_GCLK3_SOURCE,
|
||||
.div = BOARD_GCLK3_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK4_ENABLE,
|
||||
.oov = BOARD_GCLK4_OOV,
|
||||
.oe = BOARD_GCLK4_OE,
|
||||
.runstdby = BOARD_GCLK4_RUNSTDBY,
|
||||
.source = BOARD_GCLK4_SOURCE,
|
||||
.div = BOARD_GCLK4_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK5_ENABLE,
|
||||
.oov = BOARD_GCLK5_OOV,
|
||||
.oe = BOARD_GCLK5_OE,
|
||||
.runstdby = BOARD_GCLK5_RUNSTDBY,
|
||||
.source = BOARD_GCLK5_SOURCE,
|
||||
.div = BOARD_GCLK5_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK6_ENABLE,
|
||||
.oov = BOARD_GCLK6_OOV,
|
||||
.oe = BOARD_GCLK6_OE,
|
||||
.runstdby = BOARD_GCLK6_RUNSTDBY,
|
||||
.source = BOARD_GCLK6_SOURCE,
|
||||
.div = BOARD_GCLK6_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK7_ENABLE,
|
||||
.oov = BOARD_GCLK7_OOV,
|
||||
.oe = BOARD_GCLK7_OE,
|
||||
.runstdby = BOARD_GCLK7_RUNSTDBY,
|
||||
.source = BOARD_GCLK7_SOURCE,
|
||||
.div = BOARD_GCLK7_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK8_ENABLE,
|
||||
.oov = BOARD_GCLK8_OOV,
|
||||
.oe = BOARD_GCLK8_OE,
|
||||
.runstdby = BOARD_GCLK8_RUNSTDBY,
|
||||
.source = BOARD_GCLK8_SOURCE,
|
||||
.div = BOARD_GCLK8_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK9_ENABLE,
|
||||
.oov = BOARD_GCLK9_OOV,
|
||||
.oe = BOARD_GCLK9_OE,
|
||||
.runstdby = BOARD_GCLK9_RUNSTDBY,
|
||||
.source = BOARD_GCLK9_SOURCE,
|
||||
.div = BOARD_GCLK9_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK10_ENABLE,
|
||||
.oov = BOARD_GCLK10_OOV,
|
||||
.oe = BOARD_GCLK10_OE,
|
||||
.runstdby = BOARD_GCLK10_RUNSTDBY,
|
||||
.source = BOARD_GCLK10_SOURCE,
|
||||
.div = BOARD_GCLK10_DIV
|
||||
},
|
||||
{
|
||||
.enable = BOARD_GCLK11_ENABLE,
|
||||
.oov = BOARD_GCLK11_OOV,
|
||||
.oe = BOARD_GCLK11_OE,
|
||||
.runstdby = BOARD_GCLK11_RUNSTDBY,
|
||||
.source = BOARD_GCLK11_SOURCE,
|
||||
.div = BOARD_GCLK11_DIV
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -317,7 +317,7 @@ static void sam_set_waitstates(const struct sam_clockconfig_s *config)
|
||||
{
|
||||
DEBUGASSERT(config->waitstates < 16);
|
||||
modifyreg16(SAM_NVMCTRL_CTRLA, NVMCTRL_CTRLA_RWS_MASK,
|
||||
NVMCTRL_CTRLA_RWS(config->waitstates) );
|
||||
NVMCTRL_CTRLA_RWS(config->waitstates));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -422,9 +422,9 @@ static void sam_xosc32k_configure(const struct sam_xosc32_config_s *config)
|
||||
static uint32_t sam_xoscctrl(const struct sam_xosc_config_s *config)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint8_t cfdpresc;
|
||||
uint8_t imult;
|
||||
uint8_t iptat;
|
||||
uint32_t cfdpresc;
|
||||
uint32_t imult;
|
||||
uint8_t iptat = 3;
|
||||
|
||||
/* Some settings determined by the crystal frequency */
|
||||
|
||||
@ -446,7 +446,7 @@ static uint32_t sam_xoscctrl(const struct sam_xosc_config_s *config)
|
||||
imult = 5;
|
||||
iptat = 3;
|
||||
}
|
||||
else if (config->xosc_frequency > 8000000)
|
||||
else
|
||||
{
|
||||
cfdpresc = 3;
|
||||
imult = 4;
|
||||
@ -455,7 +455,7 @@ static uint32_t sam_xoscctrl(const struct sam_xosc_config_s *config)
|
||||
|
||||
/* Get the XOSCTCTL register *configuration */
|
||||
|
||||
regval = OSCCTRL_XOSCCTRL_IPTAT(ipta) | OSCCTRL_XOSCCTRL_IMULT(imult) |
|
||||
regval = OSCCTRL_XOSCCTRL_IPTAT(iptat) | OSCCTRL_XOSCCTRL_IMULT(imult) |
|
||||
OSCCTRL_XOSCCTRL_STARTUP(config->startup) |
|
||||
OSCCTRL_XOSCCTRL_CFDPRESC(cfdpresc);
|
||||
|
||||
@ -504,15 +504,15 @@ static uint32_t sam_xoscctrl(const struct sam_xosc_config_s *config)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_xosc32k_configure
|
||||
* Name: sam_xosc0_configure
|
||||
*
|
||||
* Description:
|
||||
* Configure XOSC32K
|
||||
* Configure XOSC0K
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if BOARD_HAVE_XOSC0 != 0
|
||||
static void sam_xosc0_configure(const struct sam_clockconfig_s *config)
|
||||
static void sam_xosc0_configure(const struct sam_xosc_config_s *config)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
@ -521,11 +521,11 @@ static void sam_xosc0_configure(const struct sam_clockconfig_s *config)
|
||||
regval = sam_xoscctrl(config);
|
||||
putreg32(regval, SAM_OSCCTRL_XOSCCTRL0);
|
||||
|
||||
/* Wait for XOSC32 to become ready if it was enabled */
|
||||
/* Wait for XOSC0 to become ready if it was enabled */
|
||||
|
||||
if (config->enable)
|
||||
{
|
||||
while (getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_XOSCRDY0) == 0)
|
||||
while ((getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_XOSCRDY0) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -534,14 +534,14 @@ static void sam_xosc0_configure(const struct sam_clockconfig_s *config)
|
||||
|
||||
if (config->ondemand)
|
||||
{
|
||||
regval = getre32(SAM_OSCCTRL_XOSCCTRL0)
|
||||
regval = getreg32(SAM_OSCCTRL_XOSCCTRL0);
|
||||
regval |= OSCCTRL_XOSCCTRL_ONDEMAND;
|
||||
putreg32(regval, SAM_OSCCTRL_XOSCCTRL0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BOARD_HAVE_XOSC0 != 0
|
||||
#if BOARD_HAVE_XOSC1 != 0
|
||||
void sam_xosc1_configure(const struct sam_xosc_config_s *config)
|
||||
{
|
||||
uint32_t regval;
|
||||
@ -551,11 +551,11 @@ void sam_xosc1_configure(const struct sam_xosc_config_s *config)
|
||||
regval = sam_xoscctrl(config);
|
||||
putreg32(regval, SAM_OSCCTRL_XOSCCTRL1);
|
||||
|
||||
/* Wait for XOSC32 to become ready if it was enabled */
|
||||
/* Wait for XOSC1 to become ready if it was enabled */
|
||||
|
||||
if (config->enable)
|
||||
{
|
||||
while (getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_XOSCRDY1) == 0)
|
||||
while ((getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_XOSCRDY1) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -564,7 +564,7 @@ void sam_xosc1_configure(const struct sam_xosc_config_s *config)
|
||||
|
||||
if (config->ondemand)
|
||||
{
|
||||
regval = getre32(SAM_OSCCTRL_XOSCCTRL1)
|
||||
regval = getreg32(SAM_OSCCTRL_XOSCCTRL1);
|
||||
regval |= OSCCTRL_XOSCCTRL_ONDEMAND;
|
||||
putreg32(regval, SAM_OSCCTRL_XOSCCTRL1);
|
||||
}
|
||||
@ -782,8 +782,9 @@ static void sam_dfll_ready(const struct sam_dfll_config_s *config)
|
||||
uint32_t regval32;
|
||||
uint8_t regval8;
|
||||
|
||||
/* Check if the mode bit was set, i.e., we are in closed-loop mode. If so
|
||||
* wait for the DFLL to be ready for and for the coarse lock to be obtained.
|
||||
/* Check if the mode bit was set, i.e., we are in closed-loop mode. If so
|
||||
* wait for the DFLL to be ready for and for the coarse lock to be
|
||||
* obtained.
|
||||
*/
|
||||
|
||||
regval8 = getreg8(SAM_OSCCTRL_DPLL0CTRLB);
|
||||
@ -828,7 +829,7 @@ static void sam_dfll_gclkready(const struct sam_dfll_config_s *config)
|
||||
{
|
||||
}
|
||||
|
||||
/* Set the source of GCLK0 to the configured source. */
|
||||
/* Set the source of GCLK0 to to the configured source. */
|
||||
|
||||
regval32 = getreg32(SAM_GCLK_GENCTRL(0));
|
||||
regval32 &= ~GCLK_GENCTRL_SRC_MASK;
|
||||
@ -854,7 +855,9 @@ static void sam_dpll_gclkchannel(uint8_t chan,
|
||||
|
||||
if (config->refclk == 0 && !sam_gclk_chan_locked(chan))
|
||||
{
|
||||
/* Yes.. configure the GCLK channel that will be used as refclk source */
|
||||
/* Yes.. configure the GCLK channel that will be used as
|
||||
* refclk source.
|
||||
*/
|
||||
|
||||
sam_gclk_chan_enable(chan, config->gclk, (bool)config->reflock);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "sam_periphclks.h"
|
||||
#include "sam_port.h"
|
||||
#include "sam_eic.h"
|
||||
#include "hardware/sam_pac.h"
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
@ -135,7 +136,7 @@ int sam_eic_initialize(void)
|
||||
|
||||
/* Configure the EIC APB clock */
|
||||
|
||||
sam_apb_eic_enableperiph();
|
||||
sam_apb_eic_enableperiph(); /* SAM_MCLK_APBAMASK(MCLK_APBAMASK_EIC) */
|
||||
|
||||
/* Use the selected GCLK_EIC. Some optional functions need a peripheral
|
||||
* clock, which can either be a generic clock (GCLK_EIC, for wider
|
||||
@ -144,13 +145,13 @@ int sam_eic_initialize(void)
|
||||
* and enabled before using the peripheral.
|
||||
*/
|
||||
|
||||
regaddr = SAM_GCLK_PCHCTRL(GCLK_CHAN_EIC);
|
||||
regaddr = SAM_GCLK_PCHCTRL(GCLK_CHAN_EIC); /* (GCLK_CHAN_EIC) */
|
||||
regval = GCLK_PCHCTRL_GEN(BOARD_GCLK_EIC) | GCLK_PCHCTRL_CHEN;
|
||||
putreg32(regval, regaddr);
|
||||
|
||||
/* Enable the EIC, selecting clocking via the GCLK_EIC */
|
||||
|
||||
putreg8(EIC_CTRLA_ENABLE | EIC_CTRLA_ENABLE, SAM_EIC_CTRLA);
|
||||
putreg8(EIC_CTRLA_ENABLE, SAM_EIC_CTRLA);
|
||||
sam_eic_syncwait();
|
||||
|
||||
sam_eic_dumpregs();
|
||||
@ -179,6 +180,11 @@ int sam_eic_configure(uint8_t eirq, port_pinset_t pinset)
|
||||
uint32_t val;
|
||||
uint32_t config;
|
||||
|
||||
/* Disable the EIC: 23.6.2.1 */
|
||||
|
||||
putreg8(0, SAM_EIC_CTRLA);
|
||||
sam_eic_syncwait();
|
||||
|
||||
/* Determine which of the CONFIG[0:1] registers to write to */
|
||||
|
||||
if (eirq < 8)
|
||||
@ -196,6 +202,11 @@ int sam_eic_configure(uint8_t eirq, port_pinset_t pinset)
|
||||
val = EIC_CONFIG0_SENSE_FALL(eirq);
|
||||
}
|
||||
|
||||
if ((pinset & PORT_INT_HIGH) != 0)
|
||||
{
|
||||
val = EIC_CONFIG0_SENSE_HIGH(eirq);
|
||||
}
|
||||
|
||||
val |= EIC_CONFIG0_FILTEN(eirq);
|
||||
}
|
||||
else /* if (eirq < 16) */
|
||||
@ -213,7 +224,14 @@ int sam_eic_configure(uint8_t eirq, port_pinset_t pinset)
|
||||
val = EIC_CONFIG1_SENSE_FALL(eirq);
|
||||
}
|
||||
|
||||
val |= EIC_CONFIG1_FILTEN(eirq);
|
||||
if ((pinset & PORT_INT_HIGH) != 0)
|
||||
{
|
||||
val = EIC_CONFIG1_SENSE_HIGH(eirq);
|
||||
}
|
||||
|
||||
config = getreg32(SAM_EIC_EVCTRL);
|
||||
config |= EIC_EXTINT(eirq);
|
||||
putreg32(config, SAM_EIC_EVCTRL);
|
||||
}
|
||||
|
||||
/* Write the new config to the CONFIGn register */
|
||||
@ -222,9 +240,10 @@ int sam_eic_configure(uint8_t eirq, port_pinset_t pinset)
|
||||
config |= val;
|
||||
putreg32(config, reg);
|
||||
|
||||
/* Enable interrupt generation for this pin */
|
||||
/* Enable the EIC, selecting clocking via the GCLK_EIC */
|
||||
|
||||
putreg32(EIC_EXTINT(eirq), SAM_EIC_INTENSET);
|
||||
putreg8(EIC_CTRLA_ENABLE, SAM_EIC_CTRLA);
|
||||
sam_eic_syncwait();
|
||||
|
||||
sam_eic_dumpregs();
|
||||
return OK;
|
||||
@ -248,7 +267,9 @@ int sam_eic_irq_ack(int irq)
|
||||
{
|
||||
int eirq = irq - SAM_IRQ_EXTINT0;
|
||||
|
||||
putreg32(EIC_EXTINT(eirq), SAM_EIC_INTENCLR);
|
||||
irqinfo("sam_eic_irq_ack: irq=%d eirq=%d EIC_EXTINT=0x%x\n", irq,
|
||||
eirq, EIC_EXTINT(eirq));
|
||||
putreg32(EIC_EXTINT(eirq), SAM_EIC_INTFLAG);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,8 @@ int sam_eic_configure(uint8_t eirq, port_pinset_t pinset);
|
||||
|
||||
int sam_eic_irq_ack(int irq);
|
||||
|
||||
void sam_eic_dumpregs(void);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
259
arch/arm/src/samd5e5/sam_freerun.c
Normal file
259
arch/arm/src/samd5e5/sam_freerun.c
Normal file
@ -0,0 +1,259 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/sam_freerun.c
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
|
||||
#include "sam_freerun.h"
|
||||
|
||||
#ifdef CONFIG_SAMD5E5_FREERUN
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_freerun_handler
|
||||
*
|
||||
* Description:
|
||||
* Timer interrupt callback. When the freerun timer counter overflows,
|
||||
* this interrupt will occur. We will just increment an overflow count.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tch - The handle that represents the timer state
|
||||
* arg - An opaque argument provided when the interrupt was registered
|
||||
* sr - The value of the timer interrupt status register at the time
|
||||
* that the interrupt occurred.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sam_freerun_handler(TC_HANDLE tch, void *arg, uint32_t sr)
|
||||
{
|
||||
struct sam_freerun_s *freerun = (struct sam_freerun_s *)arg;
|
||||
|
||||
DEBUGASSERT(freerun && freerun->overflow < UINT16_MAX);
|
||||
freerun->overflow++;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_freerun_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the freerun timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure
|
||||
* chan Timer counter channel to be used. See the TC_CHAN*
|
||||
* definitions in arch/arm/src/samd5e5/sam_tc.h.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan,
|
||||
uint16_t resolution)
|
||||
{
|
||||
uint32_t frequency;
|
||||
|
||||
tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
|
||||
DEBUGASSERT(freerun && resolution > 0);
|
||||
|
||||
/* Get the TC frequency the corresponds to the requested resolution */
|
||||
|
||||
frequency = USEC_PER_SEC / (uint32_t)resolution;
|
||||
|
||||
freerun->tch = sam_tc_allocate(chan, frequency);
|
||||
if (!freerun->tch)
|
||||
{
|
||||
tmrerr("ERROR: Failed to allocate timer channel %d\n", chan);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Initialize the remaining fields in the state structure and return
|
||||
* success.
|
||||
*/
|
||||
|
||||
freerun->chan = chan;
|
||||
freerun->running = false;
|
||||
freerun->overflow = 0;
|
||||
|
||||
/* Set up to receive the callback when the counter overflow occurs */
|
||||
|
||||
(void)sam_tc_attach(freerun->tch, sam_freerun_handler,
|
||||
freerun, TC_INTFLAG_OVF);
|
||||
|
||||
/* Start the counter */
|
||||
|
||||
sam_tc_start(freerun->tch);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_freerun_counter
|
||||
*
|
||||
* Description:
|
||||
* Read the counter register of the free-running timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_freerun_initialize();
|
||||
* ts The location in which to return the time from the free-running
|
||||
* timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts)
|
||||
{
|
||||
uint64_t usec;
|
||||
uint32_t counter;
|
||||
uint32_t verify;
|
||||
uint8_t sr;
|
||||
uint32_t overflow;
|
||||
uint32_t sec;
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(freerun && freerun->tch && ts);
|
||||
|
||||
/* Temporarily disable the overflow counter.
|
||||
* NOTE that we have to be here because sam_tc_getpending()
|
||||
* will reset the pending interrupt status.
|
||||
* If we do not handle the overflow here then, it will be lost.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
overflow = freerun->overflow;
|
||||
counter = sam_tc_getcounter(freerun->tch);
|
||||
sr = sam_tc_getpending(freerun->tch);
|
||||
verify = sam_tc_getcounter(freerun->tch);
|
||||
|
||||
/* If an interrupt was pending before we re-enabled interrupts,
|
||||
* then the overflow needs to be incremented.
|
||||
*/
|
||||
|
||||
if ((sr & TC_INTFLAG_OVF) != 0)
|
||||
{
|
||||
/* Increment the overflow count and use the value of the
|
||||
* guaranteed to be AFTER the overflow occurred.
|
||||
*/
|
||||
|
||||
overflow++;
|
||||
counter = verify;
|
||||
|
||||
/* Update freerun overflow counter. */
|
||||
|
||||
freerun->overflow = overflow;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
tmrinfo("counter=%u (%u) overflow=%u, sr=0x%x\n",
|
||||
counter, verify, overflow, sr);
|
||||
|
||||
/* Convert the whole thing to units of microseconds.
|
||||
*
|
||||
* frequency = ticks / second
|
||||
* seconds = ticks * frequency
|
||||
* usecs = (ticks * USEC_PER_SEC) / frequency;
|
||||
*/
|
||||
|
||||
usec = ((((uint64_t)overflow << 32) + (uint64_t)counter) * USEC_PER_SEC) /
|
||||
sam_tc_divfreq(freerun->tch);
|
||||
|
||||
/* And return the value of the timer */
|
||||
|
||||
sec = (uint32_t)(usec / USEC_PER_SEC);
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
|
||||
|
||||
tmrinfo("usec=%llu ts=(%lu, %lu)\n",
|
||||
usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_freerun_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Stop the free-running timer and release all resources that it uses.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_freerun_initialize();
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_freerun_uninitialize(struct sam_freerun_s *freerun)
|
||||
{
|
||||
DEBUGASSERT(freerun && freerun->tch);
|
||||
|
||||
/* Now we can disable the timer interrupt and disable the timer. */
|
||||
|
||||
sam_tc_attach(freerun->tch, NULL, NULL, 0);
|
||||
sam_tc_stop(freerun->tch);
|
||||
|
||||
/* Free the timer */
|
||||
|
||||
sam_tc_free(freerun->tch);
|
||||
freerun->tch = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SAMD5E5_FREERUN */
|
151
arch/arm/src/samd5e5/sam_freerun.h
Normal file
151
arch/arm/src/samd5e5/sam_freerun.h
Normal file
@ -0,0 +1,151 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/sam_freerun.h
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAMD5E5_SAM_FREERUN_H
|
||||
#define __ARCH_ARM_SRC_SAMD5E5_SAM_FREERUN_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sam_tc.h"
|
||||
|
||||
#ifdef CONFIG_SAMD5E5_FREERUN
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define FREERUN_INITIALIZED(s) (((s)->tch) != NULL)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* The freerun client must allocate an instance of this structure and called
|
||||
* sam_freerun_initialize() before using the freerun facilities. The client
|
||||
* should not access the contents of this structure directly since the
|
||||
* contents are subject to change.
|
||||
*/
|
||||
|
||||
struct sam_freerun_s
|
||||
{
|
||||
uint8_t chan; /* The timer/counter in use */
|
||||
bool running; /* True: the timer is running */
|
||||
uint32_t overflow; /* Timer counter overflow */
|
||||
TC_HANDLE tch; /* Handle returned by sam_tc_initialize() */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_freerun_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the freerun timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure
|
||||
* chan Timer counter channel to be used. See the TC_CHAN*
|
||||
* definitions in arch/arm/src/sama5/sam_tc.h.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan,
|
||||
uint16_t resolution);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_freerun_counter
|
||||
*
|
||||
* Description:
|
||||
* Read the counter register of the free-running timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_freerun_initialize();
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_freerun_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Stop the free-running timer and release all resources that it uses.
|
||||
*
|
||||
* Input Parameters:
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_freerun_initialize();
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_freerun_uninitialize(struct sam_freerun_s *freerun);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SAMD5E5_FREERUN */
|
||||
#endif /* __ARCH_ARM_SRC_SAMD5E5_SAM_FREERUN_H */
|
459
arch/arm/src/samd5e5/sam_oneshot.c
Normal file
459
arch/arm/src/samd5e5/sam_oneshot.c
Normal file
@ -0,0 +1,459 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/sam_oneshot.c
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
|
||||
#include "sam_oneshot.h"
|
||||
#include "sam_freerun.h"
|
||||
|
||||
#ifdef CONFIG_SAMD5E5_ONESHOT
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_handler
|
||||
*
|
||||
* Description:
|
||||
* Timer interrupt callback. When the oneshot timer interrupt expires,
|
||||
* this function will be called. It will forward the call to the next
|
||||
* level up.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tch - The handle that represents the timer state
|
||||
* arg - An opaque argument provided when the interrupt was registered
|
||||
* sr - The value of the timer interrupt status register at the time
|
||||
* that the interrupt occurred.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sam_oneshot_handler(TC_HANDLE tch, void *arg, uint32_t sr)
|
||||
{
|
||||
struct sam_oneshot_s *oneshot = (struct sam_oneshot_s *)arg;
|
||||
oneshot_handler_t oneshot_handler;
|
||||
void *oneshot_arg;
|
||||
|
||||
tmrinfo("Expired...\n");
|
||||
DEBUGASSERT(oneshot && oneshot->handler);
|
||||
|
||||
/* The clock was stopped, but not disabled when the RC match occurred.
|
||||
* Disable the TC now and disable any further interrupts.
|
||||
*/
|
||||
|
||||
sam_tc_attach(oneshot->tch, NULL, NULL, 0);
|
||||
sam_tc_stop(oneshot->tch);
|
||||
|
||||
/* The timer is no longer running */
|
||||
|
||||
oneshot->running = false;
|
||||
|
||||
/* Forward the event, clearing out any vestiges */
|
||||
|
||||
oneshot_handler = (oneshot_handler_t)oneshot->handler;
|
||||
oneshot->handler = NULL;
|
||||
oneshot_arg = (void *)oneshot->arg;
|
||||
oneshot->arg = NULL;
|
||||
#ifdef CONFIG_SAMD5E5_FREERUN
|
||||
oneshot->start_count = 0;
|
||||
#endif
|
||||
|
||||
oneshot_handler(oneshot_arg);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the oneshot timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure
|
||||
* chan Timer counter channel to be used. See the TC_CHAN*
|
||||
* definitions in arch/arm/src/samd5e5/sam_tc.h.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
|
||||
uint16_t resolution)
|
||||
{
|
||||
uint32_t frequency;
|
||||
|
||||
tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
|
||||
DEBUGASSERT(oneshot && resolution > 0);
|
||||
|
||||
/* Get the TC frequency the corresponds to the requested resolution */
|
||||
|
||||
frequency = USEC_PER_SEC / (uint32_t)resolution;
|
||||
|
||||
oneshot->tch = sam_tc_allocate(chan, frequency);
|
||||
if (!oneshot->tch)
|
||||
{
|
||||
tmrerr("ERROR: Failed to allocate timer channel %d\n", chan);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Initialize the remaining fields in the state structure and return
|
||||
* success.
|
||||
*/
|
||||
|
||||
oneshot->chan = chan;
|
||||
oneshot->running = false;
|
||||
oneshot->handler = NULL;
|
||||
oneshot->arg = NULL;
|
||||
#ifdef CONFIG_SAMD5E5_FREERUN
|
||||
oneshot->start_count = 0;
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_max_delay
|
||||
*
|
||||
* Description:
|
||||
* Return the maximum delay supported by the one shot timer (in
|
||||
* microseconds).
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_oneshot_initialize();
|
||||
* usec The location in which to return the maximum delay.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_oneshot_max_delay(struct sam_oneshot_s *oneshot, uint64_t *usec)
|
||||
{
|
||||
DEBUGASSERT(oneshot != NULL && usec != NULL);
|
||||
*usec = (0xffffull * USEC_PER_SEC) /
|
||||
(uint64_t)sam_tc_divfreq(oneshot->tch);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_start
|
||||
*
|
||||
* Description:
|
||||
* Start the oneshot timer
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_oneshot_initialize();
|
||||
* handler The function to call when when the oneshot timer expires.
|
||||
* arg An opaque argument that will accompany the callback.
|
||||
* ts Provides the duration of the one shot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_oneshot_start(struct sam_oneshot_s *oneshot,
|
||||
struct sam_freerun_s *freerun,
|
||||
oneshot_handler_t handler, void *arg,
|
||||
const struct timespec *ts)
|
||||
{
|
||||
uint64_t usec;
|
||||
uint64_t regval;
|
||||
irqstate_t flags;
|
||||
|
||||
tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n",
|
||||
handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
DEBUGASSERT(oneshot && handler && ts);
|
||||
|
||||
/* Was the oneshot already running? */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (oneshot->running)
|
||||
{
|
||||
/* Yes.. then cancel it */
|
||||
|
||||
tmrinfo("Already running... cancelling\n");
|
||||
(void)sam_oneshot_cancel(oneshot, freerun, NULL);
|
||||
}
|
||||
|
||||
/* Save the new handler and its argument */
|
||||
|
||||
oneshot->handler = handler;
|
||||
oneshot->arg = arg;
|
||||
|
||||
/* Express the delay in microseconds */
|
||||
|
||||
usec = (uint64_t)ts->tv_sec * USEC_PER_SEC + (uint64_t)(ts->tv_nsec /
|
||||
NSEC_PER_USEC);
|
||||
|
||||
/* Get the timer counter frequency and determine
|
||||
* the number of counts need to achieve the requested delay.
|
||||
*
|
||||
* frequency = ticks / second
|
||||
* ticks = seconds * frequency
|
||||
* = (usecs * frequency) / USEC_PER_SEC;
|
||||
*/
|
||||
|
||||
regval = (usec * (uint64_t)sam_tc_divfreq(oneshot->tch)) / USEC_PER_SEC;
|
||||
|
||||
tmrinfo("usec=%llu * %lu / %lu -> regval=0x%08llx\n", usec,
|
||||
sam_tc_divfreq(oneshot->tch), USEC_PER_SEC, regval);
|
||||
DEBUGASSERT(regval <= UINT32_MAX);
|
||||
|
||||
/* Set up to receive the callback when the interrupt occurs */
|
||||
|
||||
(void)sam_tc_attach(oneshot->tch, sam_oneshot_handler,
|
||||
oneshot, TC_INTFLAG_MC0);
|
||||
|
||||
/* Set CC0 so that an event will be triggered when COUNT register
|
||||
* counts up to CC0.
|
||||
*/
|
||||
|
||||
sam_tc_setregister(oneshot->tch, TC_REGCC0, (uint32_t)regval);
|
||||
sam_tc_setregister(oneshot->tch, TC_REGCC1, (uint32_t)0xffffffff);
|
||||
|
||||
/* Start the counter */
|
||||
|
||||
sam_tc_start(oneshot->tch);
|
||||
|
||||
#ifdef CONFIG_SAMD5E5_FREERUN
|
||||
/* The function sam_tc_start() starts the timer/counter by setting the
|
||||
* bits TC_CCR_CLKEN and TC_CCR_SWTRG in the channel control register.
|
||||
* The first one enables the timer/counter the latter performs an
|
||||
* software trigger, which starts the clock and sets the counter
|
||||
* register to zero. This reset is performed with the next valid edge
|
||||
* of the selected clock. Thus it can take up USEC_PER_TICK microseconds
|
||||
* until the counter register becomes zero.
|
||||
*
|
||||
* If the timer is canceled within this period the counter register holds
|
||||
* the counter value for the last timer/counter run. To circumvent this
|
||||
* the counter value of the freerun timer/counter is stored at each start
|
||||
* of the oneshot timer/counter.
|
||||
*
|
||||
* The function up_timer_gettime() could also be used for this but it takes
|
||||
* too long. If up_timer_gettime() is called within this function the
|
||||
* problem vanishes at least if compiled with no optimisation.
|
||||
*/
|
||||
|
||||
if (freerun != NULL)
|
||||
{
|
||||
oneshot->start_count = sam_tc_getcounter(freerun->tch);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enable interrupts. We should get the callback when the interrupt
|
||||
* occurs.
|
||||
*/
|
||||
|
||||
oneshot->running = true;
|
||||
leave_critical_section(flags);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel the oneshot timer and return the time remaining on the timer.
|
||||
*
|
||||
* NOTE: This function may execute at a high rate with no timer running (as
|
||||
* when pre-emption is enabled and disabled).
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_oneshot_initialize();
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer. A time of zero is returned if the timer is
|
||||
* not running. ts may be zero in which case the time remaining
|
||||
* is not returned.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
||||
* the timer is not active should also return success; a negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_oneshot_cancel(struct sam_oneshot_s *oneshot,
|
||||
struct sam_freerun_s *freerun, struct timespec *ts)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint64_t usec;
|
||||
uint64_t sec;
|
||||
uint64_t nsec;
|
||||
uint32_t count;
|
||||
uint32_t rc;
|
||||
|
||||
/* Was the timer running? */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (!oneshot->running)
|
||||
{
|
||||
/* No.. Just return zero timer remaining and successful cancellation.
|
||||
* This function may execute at a high rate with no timer running
|
||||
* (as when pre-emption is enabled and disabled).
|
||||
*/
|
||||
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = 0;
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Yes.. Get the timer counter and rc registers and stop the counter. If
|
||||
* the counter expires while we are doing this, the counter clock will be
|
||||
* stopped, but the clock will not be disabled.
|
||||
*
|
||||
* The expected behavior is that the counter register will freezes at
|
||||
* a value equal to the RC register when the timer expires. The counter
|
||||
* should have values between 0 and RC in all other cased.
|
||||
*
|
||||
* REVISIT: This does not appear to be the case.
|
||||
*/
|
||||
|
||||
tmrinfo("Cancelling...\n");
|
||||
|
||||
count = sam_tc_getcounter(oneshot->tch);
|
||||
rc = sam_tc_getregister(oneshot->tch, TC_REGCC0);
|
||||
|
||||
#ifdef CONFIG_SAMD5E5_FREERUN
|
||||
/* In the case the timer/counter was canceled very short after its start,
|
||||
* the counter register can hold the wrong value (the value of the last
|
||||
* run). To prevent this the counter value is set to zero if not at
|
||||
* least on tick passed since the start of the timer/counter.
|
||||
*/
|
||||
|
||||
if (count > 0 && freerun != NULL &&
|
||||
sam_tc_getcounter(freerun->tch) == oneshot->start_count)
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now we can disable the interrupt and stop the timer. */
|
||||
|
||||
sam_tc_attach(oneshot->tch, NULL, NULL, 0);
|
||||
sam_tc_stop(oneshot->tch);
|
||||
|
||||
oneshot->running = false;
|
||||
oneshot->handler = NULL;
|
||||
oneshot->arg = NULL;
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Did the caller provide us with a location to return the time
|
||||
* remaining?
|
||||
*/
|
||||
|
||||
if (ts)
|
||||
{
|
||||
/* Yes.. then calculate and return the time remaining on the
|
||||
* oneshot timer.
|
||||
*/
|
||||
|
||||
tmrinfo("rc=%lu count=%lu usec=%lu\n",
|
||||
(unsigned long)rc, (unsigned long)count, (unsigned long)usec);
|
||||
|
||||
/* REVISIT: I am not certain why the timer counter value sometimes
|
||||
* exceeds RC. Might be a bug, or perhaps the counter does not stop
|
||||
* in all cases.
|
||||
*/
|
||||
|
||||
if (count >= rc)
|
||||
{
|
||||
/* No time remaining (?) */
|
||||
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The total time remaining is the difference. Convert the that
|
||||
* to units of microseconds.
|
||||
*
|
||||
* frequency = ticks / second
|
||||
* seconds = ticks * frequency
|
||||
* usecs = (ticks * USEC_PER_SEC) / frequency;
|
||||
*/
|
||||
|
||||
usec = (((uint64_t)(rc - count)) * USEC_PER_SEC) /
|
||||
sam_tc_divfreq(oneshot->tch);
|
||||
|
||||
/* Each time the timer/counter is canceled the time calculated from
|
||||
* the two registers (counter and REGC) is accurate up to an error
|
||||
* between 0 and USEC_PER_TICK microseconds. To correct this error
|
||||
* one tick which means USEC_PER_TICK microseconds are subtracted.
|
||||
*/
|
||||
|
||||
usec = usec > USEC_PER_TICK ? usec - USEC_PER_TICK : 0;
|
||||
|
||||
/* Return the time remaining in the correct form */
|
||||
|
||||
sec = usec / USEC_PER_SEC;
|
||||
nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
|
||||
|
||||
ts->tv_sec = (time_t)sec;
|
||||
ts->tv_nsec = (unsigned long)nsec;
|
||||
}
|
||||
|
||||
tmrinfo("remaining (%lu, %lu)\n",
|
||||
(unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SAMD5E5_ONESHOT */
|
212
arch/arm/src/samd5e5/sam_oneshot.h
Normal file
212
arch/arm/src/samd5e5/sam_oneshot.h
Normal file
@ -0,0 +1,212 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/sam_oneshot.c
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAMD5E5_SAM_ONESHOT_H
|
||||
#define __ARCH_ARM_SRC_SAMD5E5_SAM_ONESHOT_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sam_tc.h"
|
||||
|
||||
#ifdef CONFIG_SAMD5E5_ONESHOT
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ONESHOT_INITIALIZED(s) (((s)->tch) != NULL)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This describes the callback function that will be invoked when the oneshot
|
||||
* timer expires. The oneshot fires, the client will receive:
|
||||
*
|
||||
* arg - The opaque argument provided when the interrupt was registered
|
||||
*/
|
||||
|
||||
typedef void (*oneshot_handler_t)(void *arg);
|
||||
|
||||
/* The oneshot client must allocate an instance of this structure and called
|
||||
* sam_oneshot_initialize() before using the oneshot facilities. The client
|
||||
* should not access the contents of this structure directly since the
|
||||
* contents are subject to change.
|
||||
*/
|
||||
|
||||
struct sam_oneshot_s
|
||||
{
|
||||
uint8_t chan; /* The timer/counter in use */
|
||||
volatile bool running; /* True: the timer is running */
|
||||
TC_HANDLE tch; /* Handle returned by
|
||||
* sam_tc_initialize() */
|
||||
volatile oneshot_handler_t handler; /* Oneshot expiration callback */
|
||||
volatile void *arg; /* The argument that will accompany
|
||||
* the callback */
|
||||
#ifdef CONFIG_SAMD5E5_FREERUN
|
||||
volatile uint32_t start_count; /* Stores the value of the freerun counter,
|
||||
* at each start of the onshot timer. Is neccesary
|
||||
* to find out if the onshot counter was updated
|
||||
* correctly at the time of the call to
|
||||
* sam_oneshot_cancel or not. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the oneshot timer wrapper
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure
|
||||
* chan Timer counter channel to be used. See the TC_CHAN*
|
||||
* definitions in arch/arm/src/samd5e5/sam_tc.h.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan,
|
||||
uint16_t resolution);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_max_delay
|
||||
*
|
||||
* Description:
|
||||
* Return the maximum delay supported by the one shot timer (in
|
||||
* microseconds).
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_oneshot_initialize();
|
||||
* usec The location in which to return the maximum delay.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_oneshot_max_delay(struct sam_oneshot_s *oneshot, uint64_t *usec);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_start
|
||||
*
|
||||
* Description:
|
||||
* Start the oneshot timer
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_oneshot_initialize();
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_freerun_initialize(). May be NULL if there is no matching
|
||||
* free-running timer.
|
||||
* handler The function to call when when the oneshot timer expires.
|
||||
* arg An opaque argument that will accompany the callback.
|
||||
* ts Provides the duration of the one shot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct sam_freerun_s;
|
||||
int sam_oneshot_start(struct sam_oneshot_s *oneshot,
|
||||
struct sam_freerun_s *freerun,
|
||||
oneshot_handler_t handler, void *arg,
|
||||
const struct timespec *ts);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel the oneshot timer and return the time remaining on the timer.
|
||||
*
|
||||
* NOTE: This function may execute at a high rate with no timer running (as
|
||||
* when pre-emption is enabled and disabled).
|
||||
*
|
||||
* Input Parameters:
|
||||
* oneshot Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_oneshot_initialize();
|
||||
* freerun Caller allocated instance of the freerun state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* sam_freerun_initialize(). May be NULL if there is no matching
|
||||
* free-running timer.
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer. A time of zero is returned if the timer is
|
||||
* not running.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
||||
* the timer is not active should also return success; a negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct sam_freerun_s;
|
||||
int sam_oneshot_cancel(struct sam_oneshot_s *oneshot,
|
||||
struct sam_freerun_s *freerun, struct timespec *ts);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SAMD5E5_ONESHOT */
|
||||
#endif /* __ARCH_ARM_SRC_SAMD5E5_SAM_ONESHOT_H */
|
336
arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c
Normal file
336
arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c
Normal file
@ -0,0 +1,336 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/timers/oneshot.h>
|
||||
|
||||
#include "sam_oneshot.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure describes the state of oneshot timer lower-half driver */
|
||||
|
||||
struct sam_oneshot_lowerhalf_s
|
||||
{
|
||||
/* This is the part of the lower half driver that is visible to the upper-
|
||||
* half client of the driver. This must be the first thing in this
|
||||
* structure so that pointers to struct oneshot_lowerhalf_s are cast
|
||||
* compatible to struct sam_oneshot_lowerhalf_s and vice versa.
|
||||
*/
|
||||
|
||||
struct oneshot_lowerhalf_s lh; /* Common lower-half driver fields */
|
||||
|
||||
/* Private lower half data follows */
|
||||
|
||||
struct sam_oneshot_s oneshot; /* SAM-specific oneshot state */
|
||||
oneshot_callback_t callback; /* internal handler that receives callback */
|
||||
FAR void *arg; /* Argument that is passed to the handler */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void sam_oneshot_handler(void *arg);
|
||||
|
||||
static int sam_max_delay(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts);
|
||||
static int sam_start(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
FAR const struct timespec *ts);
|
||||
static int sam_cancel(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Lower half operations */
|
||||
|
||||
static const struct oneshot_operations_s g_oneshot_ops =
|
||||
{
|
||||
.max_delay = sam_max_delay,
|
||||
.start = sam_start,
|
||||
.cancel = sam_cancel,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_handler
|
||||
*
|
||||
* Description:
|
||||
* Timer expiration handler
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - Should be the same argument provided when sam_oneshot_start()
|
||||
* was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sam_oneshot_handler(void *arg)
|
||||
{
|
||||
FAR struct sam_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct sam_oneshot_lowerhalf_s *)arg;
|
||||
oneshot_callback_t callback;
|
||||
FAR void *cbarg;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Perhaps the callback was nullified in a race condition with
|
||||
* sam_cancel?
|
||||
*/
|
||||
|
||||
if (priv->callback)
|
||||
{
|
||||
/* Sample and nullify BEFORE executing callback (in case the callback
|
||||
* restarts the oneshot).
|
||||
*/
|
||||
|
||||
callback = priv->callback;
|
||||
cbarg = priv->arg;
|
||||
priv->callback = NULL;
|
||||
priv->arg = NULL;
|
||||
|
||||
/* Then perform the callback */
|
||||
|
||||
callback(&priv->lh, cbarg);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_max_delay
|
||||
*
|
||||
* Description:
|
||||
* Determine the maximum delay of the one-shot timer (in microseconds)
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower An instance of the lower-half oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* oneshot_initialize();
|
||||
* ts The location in which to return the maxumum delay.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sam_max_delay(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts)
|
||||
{
|
||||
FAR struct sam_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct sam_oneshot_lowerhalf_s *)lower;
|
||||
uint64_t usecs;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL && ts != NULL);
|
||||
ret = sam_oneshot_max_delay(&priv->oneshot, &usecs);
|
||||
if (ret >= 0)
|
||||
{
|
||||
uint64_t sec = usecs / 1000000;
|
||||
usecs -= 1000000 * sec;
|
||||
|
||||
ts->tv_sec = (time_t)sec;
|
||||
ts->tv_nsec = (long)(usecs * 1000);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_start
|
||||
*
|
||||
* Description:
|
||||
* Start the oneshot timer
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower An instance of the lower-half oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* oneshot_initialize();
|
||||
* handler The function to call when when the oneshot timer expires.
|
||||
* arg An opaque argument that will accompany the callback.
|
||||
* ts Provides the duration of the one shot timer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sam_start(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
FAR const struct timespec *ts)
|
||||
{
|
||||
FAR struct sam_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct sam_oneshot_lowerhalf_s *)lower;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL && callback != NULL && ts != NULL);
|
||||
|
||||
/* Save the callback information and start the timer */
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->callback = callback;
|
||||
priv->arg = arg;
|
||||
ret = sam_oneshot_start(&priv->oneshot, NULL,
|
||||
sam_oneshot_handler, priv, ts);
|
||||
leave_critical_section(flags);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: sam_oneshot_start failed: %d\n", flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel the oneshot timer and return the time remaining on the timer.
|
||||
*
|
||||
* NOTE: This function may execute at a high rate with no timer running (as
|
||||
* when pre-emption is enabled and disabled).
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower Caller allocated instance of the oneshot state structure. This
|
||||
* structure must have been previously initialized via a call to
|
||||
* oneshot_initialize();
|
||||
* ts The location in which to return the time remaining on the
|
||||
* oneshot timer. A time of zero is returned if the timer is
|
||||
* not running.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
||||
* the timer is not active should also return success; a negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sam_cancel(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts)
|
||||
{
|
||||
FAR struct sam_oneshot_lowerhalf_s *priv =
|
||||
(FAR struct sam_oneshot_lowerhalf_s *)lower;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Cancel the timer */
|
||||
|
||||
flags = enter_critical_section();
|
||||
ret = sam_oneshot_cancel(&priv->oneshot, NULL, ts);
|
||||
priv->callback = NULL;
|
||||
priv->arg = NULL;
|
||||
leave_critical_section(flags);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: sam_oneshot_cancel failed: %d\n", flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: oneshot_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the oneshot timer and return a oneshot lower half driver
|
||||
* instance.
|
||||
*
|
||||
* Input Parameters:
|
||||
* chan Timer counter channel to be used.
|
||||
* resolution The required resolution of the timer in units of
|
||||
* microseconds. NOTE that the range is restricted to the
|
||||
* range of uint16_t (excluding zero).
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a non-NULL instance of the oneshot lower-half driver is
|
||||
* returned. NULL is return on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct oneshot_lowerhalf_s *oneshot_initialize(int chan,
|
||||
uint16_t resolution)
|
||||
{
|
||||
FAR struct sam_oneshot_lowerhalf_s *priv;
|
||||
int ret;
|
||||
|
||||
/* Allocate an instance of the lower half driver */
|
||||
|
||||
priv = (FAR struct sam_oneshot_lowerhalf_s *)
|
||||
kmm_zalloc(sizeof(struct sam_oneshot_lowerhalf_s));
|
||||
|
||||
if (priv == NULL)
|
||||
{
|
||||
tmrerr("ERROR: Failed to initialized state structure\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the lower-half driver structure */
|
||||
|
||||
priv->lh.ops = &g_oneshot_ops;
|
||||
|
||||
/* Initialize the contained SAM oneshot timer */
|
||||
|
||||
ret = sam_oneshot_initialize(&priv->oneshot, chan, resolution);
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: sam_oneshot_initialize failed: %d\n", ret);
|
||||
kmm_free(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &priv->lh;
|
||||
}
|
@ -57,9 +57,9 @@
|
||||
|
||||
/* Bit-encoded input to sam_portconfig() */
|
||||
|
||||
/* 24-bit Encoding. This could be compacted into 16-bits by making the bit usage
|
||||
* mode specific. However, by giving each bit field a unique position, we handle
|
||||
* bad combinations of properties safely.
|
||||
/* 24-bit Encoding. This could be compacted into 16-bits by making the bit
|
||||
* usage mode specific. However, by giving each bit field a unique position,
|
||||
* we handle bad combinations of properties safely.
|
||||
*
|
||||
* MODE BITFIELDS
|
||||
* ------------ -----------------------------
|
||||
@ -85,12 +85,13 @@
|
||||
* Peripheral: MM.. .... .... .... .... ....
|
||||
*/
|
||||
|
||||
#define PORT_MODE_SHIFT (22) /* Bits 22-23: PORT mode */
|
||||
#define PORT_MODE_SHIFT (22) /* Bits 22-23: PORT mode */
|
||||
#define PORT_MODE_MASK (3 << PORT_MODE_SHIFT)
|
||||
# define PORT_INPUT (0 << PORT_MODE_SHIFT) /* PORT Input */
|
||||
# define PORT_OUTPUT (1 << PORT_MODE_SHIFT) /* PORT Output */
|
||||
# define PORT_PERIPHERAL (2 << PORT_MODE_SHIFT) /* Controlled by peripheral */
|
||||
# define PORT_INTERRUPT (3 << PORT_MODE_SHIFT) /* Interrupting input */
|
||||
#define PORT_MODE(n) ((uint8_t)(n) << PORT_MODE_SHIFT)
|
||||
|
||||
/* Pull-up/down resistor control for inputs
|
||||
*
|
||||
@ -217,8 +218,8 @@
|
||||
# define PORT_OUTREADBACK_DISABLE (0 << PORT_OUTREADBACK_SHIFT)
|
||||
# define PORT_OUTREADBACK_ENABLE (1 << PORT_OUTREADBACK_SHIFT)
|
||||
|
||||
/* If the pin is a PORT output, then this identifies the initial output value:
|
||||
*
|
||||
/* If the pin is a PORT output, then this
|
||||
* identifies the initial output value:
|
||||
* MODE BITFIELDS
|
||||
* ------------ -----------------------------
|
||||
* 2222 1111 1111 1100 0000 0000
|
||||
@ -251,6 +252,8 @@
|
||||
# define PORT_INT_CHANGE (0 << PORT_INT_SHIFT) /* Pin change */
|
||||
# define PORT_INT_RISING (1 << PORT_INT_SHIFT) /* Rising edge */
|
||||
# define PORT_INT_FALLING (2 << PORT_INT_SHIFT) /* Falling edge */
|
||||
# define PORT_INT_BOTH (3 << PORT_INT_SHIFT) /* Both edge */
|
||||
# define PORT_INT_HIGH (4 << PORT_INT_SHIFT) /* High edge */
|
||||
|
||||
/* This identifies the PORT port:
|
||||
*
|
||||
|
1143
arch/arm/src/samd5e5/sam_tc.c
Normal file
1143
arch/arm/src/samd5e5/sam_tc.c
Normal file
File diff suppressed because it is too large
Load Diff
367
arch/arm/src/samd5e5/sam_tc.h
Normal file
367
arch/arm/src/samd5e5/sam_tc.h
Normal file
@ -0,0 +1,367 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/sam_tc.h
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAMD5E5_SAM_TC_H
|
||||
#define __ARCH_ARM_SRC_SAMD5E5_SAM_TC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "sam_config.h"
|
||||
#include "sam_port.h"
|
||||
#include "sam_periphclks.h"
|
||||
#include "hardware/sam_tc.h"
|
||||
#include "hardware/sam_pinmap.h"
|
||||
#include "semaphore.h"
|
||||
|
||||
#ifdef CONFIG_SAMD5E5_TC
|
||||
|
||||
/* Register identifier used with sam_tc_setregister */
|
||||
|
||||
#define TC_REGCC0 0
|
||||
#define TC_REGCC1 1
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* An opaque handle used to represent a timer channel */
|
||||
|
||||
typedef void *TC_HANDLE;
|
||||
|
||||
/* Timer interrupt callback. When a timer interrupt expires, the client will
|
||||
* receive:
|
||||
*
|
||||
* tch - The handle that represents the timer state
|
||||
* arg - An opaque argument provided when the interrupt was registered
|
||||
* sr - The value of the timer interrupt status register at the time
|
||||
* that the interrupt occurred.
|
||||
*/
|
||||
|
||||
typedef void (*tc_handler_t)(TC_HANDLE tch, void *arg, uint32_t sr);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
struct tc_attr_s
|
||||
{
|
||||
uint8_t tc; /* Identifies the TC peripheral */
|
||||
uint8_t irq; /* Tc IRQ number */
|
||||
uint8_t coregen; /* Source GCLK generator */
|
||||
port_pinset_t cc0; /* Pin configuration CC0 - Compare/Capture Channel */
|
||||
port_pinset_t cc1; /* Pin configuration CC1 - Compare/Capture Channel */
|
||||
uint32_t srcfreq; /* Source clock frequency */
|
||||
uintptr_t base; /* Base address of Tc registers */
|
||||
};
|
||||
|
||||
/* Setup TC -> Add the timer register settings here. */
|
||||
|
||||
struct sam_tc_dev_s
|
||||
{
|
||||
const struct tc_attr_s *attr; /* Invariant attributes of TC device */
|
||||
uint32_t mode; /* TC mode */
|
||||
uint32_t prescaler; /* TC prescaler */
|
||||
uint32_t prescsync; /* TC prescsync */
|
||||
uint8_t wave; /* TC wave mode */
|
||||
uint16_t flags; /* Transfer flags */
|
||||
uint32_t freq; /* TC freq */
|
||||
uint32_t duty; /* TC duty cycle */
|
||||
|
||||
sem_t exclsem; /* Only one thread can access at a time */
|
||||
sem_t waitsem; /* Wait for TC */
|
||||
|
||||
bool initialized; /* True: Timer data has been initialized */
|
||||
bool inuse; /* True: channel is in use */
|
||||
tc_handler_t handler; /* Attached interrupt handler */
|
||||
void *arg; /* Interrupt handler argument */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_configure
|
||||
*
|
||||
* Description:
|
||||
* Configure the interrupt edge sensitivity in CONFIGn register of the
|
||||
* tc. The interrupt will be enabled at the tc (but not at the NVIC).
|
||||
*
|
||||
* Input Parameters:
|
||||
* eirq - Pin to be configured (0..15)
|
||||
* pinset - Configuration of the pin
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_tc_configure(uint8_t tcrq, port_pinset_t pinset);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_allocate
|
||||
*
|
||||
* Description:
|
||||
* Configures a Timer Counter to operate in the given mode. The timer is
|
||||
* stopped after configuration and must be restarted with sam_tc_start().
|
||||
* All the interrupts of the timer are also disabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* channel TC channel number (see TC_CHANx definitions)
|
||||
* mode Operating mode (TC_CMR value).
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a non-NULL handle value is returned. This handle may be
|
||||
* used with subsequent timer/counter interfaces to manage the timer. A
|
||||
* NULL handle value is returned on a failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TC_HANDLE sam_tc_allocate(int channel, int frequency);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_free
|
||||
*
|
||||
* Description:
|
||||
* Release the handle previously allocated by sam_tc_allocate().
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle Channel handle previously allocated by sam_tc_allocate()
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sam_tc_free(TC_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_start
|
||||
*
|
||||
* Description:
|
||||
* Reset and Start the TC Channel. Enables the timer clock and performs a
|
||||
* software reset to start the counting.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle Channel handle previously allocated by sam_tc_allocate()
|
||||
*
|
||||
* Returned Value:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sam_tc_start(TC_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_stop
|
||||
*
|
||||
* Description:
|
||||
* Stop TC Channel. Disables the timer clock, stopping the counting.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle Channel handle previously allocated by sam_tc_allocate()
|
||||
*
|
||||
* Returned Value:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sam_tc_stop(TC_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_attach/sam_tc_detach
|
||||
*
|
||||
* Description:
|
||||
* Attach or detach an interrupt handler to the timer interrupt. The
|
||||
* interrupt is detached if the handler argument is NULL.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle The handle that represents the timer state
|
||||
* handler The interrupt handler that will be invoked when the interrupt
|
||||
* condition occurs
|
||||
* arg An opaque argument that will be provided when the interrupt
|
||||
* handler callback is executed. Ignored if handler is NULL.
|
||||
* mask The value of the timer interrupt mask register that defines
|
||||
* which interrupts should be disabled. Ignored if handler is
|
||||
* NULL.
|
||||
*
|
||||
* Returned Value:
|
||||
* The address of the previous handler, if any.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler,
|
||||
void *arg, uint32_t mask);
|
||||
|
||||
#define sam_tc_detach(h) sam_tc_attach(h, NULL, NULL, 0)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_getpending
|
||||
*
|
||||
* Description:
|
||||
* Return the current contents of the interrutp status register, clearing
|
||||
* all pending interrupts.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle The handle that represents the timer state
|
||||
*
|
||||
* Returned Value:
|
||||
* The value of the channel interrupt status register.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t sam_tc_getpending(TC_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_setregister
|
||||
*
|
||||
* Description:
|
||||
* Set TC_REGA, TC_REGB, or TC_REGC register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle Channel handle previously allocated by sam_tc_allocate()
|
||||
* regid One of {TC_REGA, TC_REGB, or TC_REGC}
|
||||
* regval Then value to set in the register
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_getregister
|
||||
*
|
||||
* Description:
|
||||
* Get the current value of the TC_REGA, TC_REGB, or TC_REGC register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle Channel handle previously allocated by sam_tc_allocate()
|
||||
* regid One of {TC_REGA, TC_REGB, or TC_REGC}
|
||||
*
|
||||
* Returned Value:
|
||||
* The value of the specified register.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t sam_tc_getregister(TC_HANDLE handle, int regid);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_getcounter
|
||||
*
|
||||
* Description:
|
||||
* Return the current value of the timer counter register
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle Channel handle previously allocated by sam_tc_allocate()
|
||||
*
|
||||
* Returned Value:
|
||||
* The current value of the timer counter register for this channel.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t sam_tc_getcounter(TC_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_infreq
|
||||
*
|
||||
* Description:
|
||||
* Return the timer input frequency, that is, the MCK frequency divided
|
||||
* down so that the timer/counter is driven within its maximum frequency.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The timer input frequency.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t sam_tc_infreq(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_divfreq
|
||||
*
|
||||
* Description:
|
||||
* Return the divided timer input frequency that is currently driving the
|
||||
* the timer counter.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle Channel handle previously allocated by sam_tc_allocate()
|
||||
*
|
||||
* Returned Value:
|
||||
* The timer counter frequency.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t sam_tc_divfreq(TC_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_tc_divisor
|
||||
*
|
||||
* Description:
|
||||
* Finds the best MCK divisor given the timer frequency and MCK. The
|
||||
* result is guaranteed to satisfy the following equation:
|
||||
*
|
||||
* (Ftcin / (div * 65536)) <= freq <= (Ftcin / div)
|
||||
*
|
||||
* where:
|
||||
* freq - the desired frequency
|
||||
* Ftcin - The timer/counter input frequency
|
||||
* div - With DIV being the highest possible value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* frequency Desired timer frequency.
|
||||
* div Divisor value.
|
||||
* tcclks TCCLKS field value for divisor.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if a proper divisor has been found, otherwise a negated errno
|
||||
* value indicating the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sam_tc_divisor(struct sam_tc_dev_s *tc, uint32_t frequency,
|
||||
uint32_t *div, uint32_t *tcclks);
|
||||
|
||||
uint32_t sam_tc_getctrla(TC_HANDLE handle);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SAMD5E5_TC */
|
||||
#endif /* __ARCH_ARM_SRC_SAMD5E5_SAM_TC_H */
|
409
arch/arm/src/samd5e5/sam_tickless.c
Normal file
409
arch/arm/src/samd5e5/sam_tickless.c
Normal file
@ -0,0 +1,409 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/samd5e5/sam_tickless.c
|
||||
*
|
||||
* Copyright 2020 Falker Automacao Agricola LTDA.
|
||||
* Author: Leomar Mateus Radke <leomar@falker.com.br>
|
||||
* Author: Ricardo Wartchow <wartchow@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Tickless OS Support.
|
||||
*
|
||||
* When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts
|
||||
* is suppressed and the platform specific code is expected to provide the
|
||||
* following custom functions.
|
||||
*
|
||||
* void arm_timer_initialize(void): Initializes the timer facilities.
|
||||
* Calledearly in the initialization sequence (by up_intialize()).
|
||||
* int up_timer_gettime(FAR struct timespec *ts): Returns the current
|
||||
* time from the platform specific time source.
|
||||
* int up_timer_cancel(void): Cancels the interval timer.
|
||||
* int up_timer_start(FAR const struct timespec *ts): Start (or re-starts)
|
||||
* the interval timer.
|
||||
*
|
||||
* The RTOS will provide the following interfaces for use by the platform-
|
||||
* specific interval timer implementation:
|
||||
*
|
||||
* void nxsched_timer_expiration(void): Called by the platform-specific
|
||||
* logic when the interval timer expires.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* SAMD5E5 Timer Usage
|
||||
*
|
||||
* This current implementation uses two timers: A one-shot timer to provide
|
||||
* the timed events and a free running timer to provide the current time.
|
||||
* Since timers are a limited resource, that could be an issue on some
|
||||
* systems.
|
||||
*
|
||||
* We could do the job with a single timer if we were to keep the single
|
||||
* timer in a free-running at all times. The SAMD5E5 timer/counters have
|
||||
* 32-bit counters with the capability to generate a compare interrupt when
|
||||
* the timer matches a compare value but also to continue counting without
|
||||
* stopping (giving another, different interrupt when the timer rolls over
|
||||
* from 0xffffffff to zero). So we could potentially just set the compare
|
||||
* at the number of ticks you want PLUS the current value of timer. Then
|
||||
* you could have both with a single timer: An interval timer and a free-
|
||||
* running counter with the same timer!
|
||||
*
|
||||
* Patches are welcome!
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "arm_arch.h"
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "sam_oneshot.h"
|
||||
#include "sam_freerun.h"
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SAMD5E5_HAVE_TC
|
||||
# error Timer/counters must be selected for the Tickless OS option
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SAMD5E5_ONESHOT
|
||||
# error CONFIG_SAMD5E5_ONESHOT must be selected for the Tickless OS option
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SAMD5E5_FREERUN
|
||||
# error CONFIG_SAMD5E5_FREERUN must be selected for the Tickless OS option
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SAMD5E5_TICKLESS_FREERUN
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN must be selected for the Tickless OS option
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SAMD5E5_TICKLESS_ONESHOT
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT must be selected for the Tickless OS option
|
||||
#endif
|
||||
|
||||
#if CONFIG_SAMD5E5_TICKLESS_ONESHOT == 0 && !defined(CONFIG_SAMD5E5_TC0)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 0 && CONFIG_SAMD5E5_TC0 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_ONESHOT == 1 && !defined(CONFIG_SAMD5E5_TC1)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 1 && CONFIG_SAMD5E5_TC1 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_ONESHOT == 2 && !defined(CONFIG_SAMD5E5_TC2)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 2 && CONFIG_SAMD5E5_TC2 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_ONESHOT == 3 && !defined(CONFIG_SAMD5E5_TC3)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 3 && CONFIG_SAMD5E5_TC3 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_ONESHOT == 4 && !defined(CONFIG_SAMD5E5_TC4)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 4 && CONFIG_SAMD5E5_TC4 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_ONESHOT == 5 && !defined(CONFIG_SAMD5E5_TC5)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 5 && CONFIG_SAMD5E5_TC5 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_ONESHOT == 6 && !defined(CONFIG_SAMD5E5_TC6)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 6 && CONFIG_SAMD5E5_TC6 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_ONESHOT == 7 && !defined(CONFIG_SAMD5E5_TC7)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT == 7 && CONFIG_SAMD5E5_TC7 not selected
|
||||
#endif
|
||||
|
||||
#if CONFIG_SAMD5E5_TICKLESS_ONESHOT < 0 || CONFIG_SAMD5E5_TICKLESS_ONESHOT > 7
|
||||
# error CONFIG_SAMD5E5_TICKLESS_ONESHOT is not valid
|
||||
#endif
|
||||
|
||||
#if CONFIG_SAMD5E5_TICKLESS_FREERUN == 0 && !defined(CONFIG_SAMD5E5_TC0)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 0 && CONFIG_SAMD5E5_TC0 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_FREERUN == 1 && !defined(CONFIG_SAMD5E5_TC1)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 1 && CONFIG_SAMD5E5_TC1 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_FREERUN == 2 && !defined(CONFIG_SAMD5E5_TC2)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 2 && CONFIG_SAMD5E5_TC2 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_FREERUN == 3 && !defined(CONFIG_SAMD5E5_TC3)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 3 && CONFIG_SAMD5E5_TC3 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_FREERUN == 4 && !defined(CONFIG_SAMD5E5_TC4)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 4 && CONFIG_SAMD5E5_TC4 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_FREERUN == 5 && !defined(CONFIG_SAMD5E5_TC5)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 5 && CONFIG_SAMD5E5_TC5 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_FREERUN == 6 && !defined(CONFIG_SAMD5E5_TC6)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 6 && CONFIG_SAMD5E5_TC6 not selected
|
||||
#elif CONFIG_SAMD5E5_TICKLESS_FREERUN == 7 && !defined(CONFIG_SAMD5E5_TC7)
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN == 7 && CONFIG_SAMD5E5_TC7 not selected
|
||||
#endif
|
||||
|
||||
#if CONFIG_SAMD5E5_TICKLESS_FREERUN < 0 || CONFIG_SAMD5E5_TICKLESS_FREERUN > 7
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN is not valid
|
||||
#endif
|
||||
|
||||
#if CONFIG_SAMD5E5_TICKLESS_FREERUN == CONFIG_SAMD5E5_TICKLESS_ONESHOT
|
||||
# error CONFIG_SAMD5E5_TICKLESS_FREERUN is the same as CONFIG_SAMD5E5_TICKLESS_ONESHOT
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct sam_tickless_s
|
||||
{
|
||||
struct sam_oneshot_s oneshot;
|
||||
struct sam_freerun_s freerun;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct sam_tickless_s g_tickless;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_oneshot_handler
|
||||
*
|
||||
* Description:
|
||||
* Called when the one shot timer expires
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called early in the initialization sequence before any special
|
||||
* concurrency protections are required.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sam_oneshot_handler(void *arg)
|
||||
{
|
||||
tmrinfo("Expired...\n");
|
||||
nxsched_timer_expiration();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initializes all platform-specific timer facilities. This function is
|
||||
* called early in the initialization sequence by up_intialize().
|
||||
* On return, the current up-time should be available from
|
||||
* up_timer_gettime() and the interval timer is ready for use (but not
|
||||
* actively timing.
|
||||
*
|
||||
* Provided by platform-specific code and called from the architecture-
|
||||
* specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called early in the initialization sequence before any special
|
||||
* concurrency protections are required.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_timer_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
|
||||
uint64_t max_delay;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* Initialize the one-shot timer */
|
||||
|
||||
ret = sam_oneshot_initialize(&g_tickless.oneshot,
|
||||
CONFIG_SAMD5E5_TICKLESS_ONESHOT,
|
||||
CONFIG_USEC_PER_TICK);
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: sam_oneshot_initialize failed\n");
|
||||
DEBUGPANIC();
|
||||
}
|
||||
|
||||
DEBUGASSERT(ONESHOT_INITIALIZED(&g_tickless.oneshot));
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
|
||||
/* Get the maximum delay of the one-shot timer in microseconds */
|
||||
|
||||
ret = sam_oneshot_max_delay(&g_tickless.oneshot, &max_delay);
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: sam_oneshot_max_delay failed\n");
|
||||
DEBUGPANIC();
|
||||
}
|
||||
|
||||
/* Convert this to configured clock ticks for use by the OS timer logic */
|
||||
|
||||
max_delay /= CONFIG_USEC_PER_TICK;
|
||||
if (max_delay > (uint64_t)UINT32_MAX)
|
||||
{
|
||||
g_oneshot_maxticks = UINT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_oneshot_maxticks = (uint32_t)max_delay;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the free-running timer */
|
||||
|
||||
ret = sam_freerun_initialize(&g_tickless.freerun,
|
||||
CONFIG_SAMD5E5_TICKLESS_FREERUN,
|
||||
CONFIG_USEC_PER_TICK);
|
||||
if (ret < 0)
|
||||
{
|
||||
tmrerr("ERROR: sam_freerun_initialize failed\n");
|
||||
DEBUGPANIC();
|
||||
}
|
||||
|
||||
DEBUGASSERT(FREERUN_INITIALIZED(&g_tickless.freerun));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_gettime
|
||||
*
|
||||
* Description:
|
||||
* Return the elapsed time since power-up (or, more correctly, since
|
||||
* arm_timer_initialize() was called). This function is functionally
|
||||
* equivalent to:
|
||||
*
|
||||
* int clock_gettime(clockid_t clockid, FAR struct timespec *ts);
|
||||
*
|
||||
* when clockid is CLOCK_MONOTONIC.
|
||||
*
|
||||
* This function provides the basis for reporting the current time and
|
||||
* also is used to eliminate error build-up from small errors in interval
|
||||
* time calculations.
|
||||
*
|
||||
* Provided by platform-specific code and called from the RTOS base code.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ts - Provides the location in which to return the up-time.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from the normal tasking context. The implementation must
|
||||
* provide whatever mutual exclusion is necessary for correct operation.
|
||||
* This can include disabling interrupts in order to assure atomic register
|
||||
* operations.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_gettime(FAR struct timespec *ts)
|
||||
{
|
||||
return FREERUN_INITIALIZED(&g_tickless.freerun) ?
|
||||
sam_freerun_counter(&g_tickless.freerun, ts) :
|
||||
-EAGAIN;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel the interval timer and return the time remaining on the timer.
|
||||
* These two steps need to be as nearly atomic as possible.
|
||||
* nxsched_timer_expiration() will not be called unless the timer is
|
||||
* restarted with up_timer_start().
|
||||
*
|
||||
* If, as a race condition, the timer has already expired when this
|
||||
* function is called, then that pending interrupt must be cleared so
|
||||
* that up_timer_start() and the remaining time of zero should be
|
||||
* returned.
|
||||
*
|
||||
* NOTE: This function may execute at a high rate with no timer running (as
|
||||
* when pre-emption is enabled and disabled).
|
||||
*
|
||||
* Provided by platform-specific code and called from the RTOS base code.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ts - Location to return the remaining time. Zero should be returned
|
||||
* if the timer is not active. ts may be zero in which case the
|
||||
* time remaining is not returned.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
||||
* the timer is not active should also return success; a negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* May be called from interrupt level handling or from the normal tasking
|
||||
* level. Interrupts may need to be disabled internally to assure
|
||||
* non-reentrancy.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_cancel(FAR struct timespec *ts)
|
||||
{
|
||||
return ONESHOT_INITIALIZED(&g_tickless.oneshot) &&
|
||||
FREERUN_INITIALIZED(&g_tickless.freerun) ?
|
||||
sam_oneshot_cancel(&g_tickless.oneshot, &g_tickless.freerun, ts) :
|
||||
-EAGAIN;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_start
|
||||
*
|
||||
* Description:
|
||||
* Start the interval timer. nxsched_timer_expiration() will be
|
||||
* called at the completion of the timeout (unless up_timer_cancel
|
||||
* is called to stop the timing.
|
||||
*
|
||||
* Provided by platform-specific code and called from the RTOS base code.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ts - Provides the time interval until nxsched_timer_expiration() is
|
||||
* called.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* May be called from interrupt level handling or from the normal tasking
|
||||
* level. Interrupts may need to be disabled internally to assure
|
||||
* non-reentrancy.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_start(FAR const struct timespec *ts)
|
||||
{
|
||||
tmrinfo("ts=(%lu, %lu)\n", (unsigned long)ts->tv_sec,
|
||||
(unsigned long)ts->tv_nsec);
|
||||
return ONESHOT_INITIALIZED(&g_tickless.oneshot) ?
|
||||
sam_oneshot_start(&g_tickless.oneshot, &g_tickless.freerun,
|
||||
sam_oneshot_handler, NULL, ts) :
|
||||
-EAGAIN;
|
||||
}
|
||||
#endif /* CONFIG_SCHED_TICKLESS */
|
@ -103,7 +103,7 @@ static int sam_timerisr(int irq, uint32_t *regs, void *arg)
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_timer_initialize
|
||||
* Function: arm_timer_initialize
|
||||
*
|
||||
* Description:
|
||||
* This function is called during start-up to initialize the timer
|
||||
@ -129,7 +129,7 @@ void up_timer_initialize(void)
|
||||
|
||||
/* Attach the timer interrupt vector */
|
||||
|
||||
irq_attach(SAM_IRQ_SYSTICK, (xcpt_t)sam_timerisr, NULL);
|
||||
(void)irq_attach(SAM_IRQ_SYSTICK, (xcpt_t)sam_timerisr, NULL);
|
||||
|
||||
/* Enable SysTick interrupts using the processor clock source. */
|
||||
|
||||
|
@ -480,6 +480,21 @@
|
||||
#define BOARD_SERCOM5_SLOW_GCLKGEN 3
|
||||
#define BOARD_SERCOM5_FREQUENCY BOARD_GCLK1_FREQUENCY
|
||||
|
||||
/* Tickless */
|
||||
|
||||
#define BOARD_TC0_PINMAP_CC0 0 /* CC0: (not used) */
|
||||
#define BOARD_TC0_PINMAP_CC1 0 /* CC1: (not used) */
|
||||
#define BOARD_TC0_GCLKGEN 3
|
||||
#define BOARD_TC0_FREQUENCY BOARD_GCLK3_FREQUENCY
|
||||
#define BOARD_TC2_PINMAP_CC0 0 /* CC0: (not used) */
|
||||
#define BOARD_TC2_PINMAP_CC1 0 /* CC1: (not used) */
|
||||
#define BOARD_TC2_GCLKGEN 3
|
||||
#define BOARD_TC2_FREQUENCY BOARD_GCLK3_FREQUENCY
|
||||
#define BOARD_TC4_PINMAP_CC0 0 /* CC0: (not used) */
|
||||
#define BOARD_TC4_PINMAP_CC1 0 /* CC1: (not used) */
|
||||
#define BOARD_TC4_GCLKGEN 3
|
||||
#define BOARD_TC4_FREQUENCY BOARD_GCLK3_FREQUENCY
|
||||
|
||||
/* USB */
|
||||
|
||||
#define BOARD_USB_GCLKGEN 1 /* GCLK1, 48MHz */
|
||||
|
Loading…
Reference in New Issue
Block a user