You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/08/18 15:42:57 UTC

[incubator-nuttx] 02/02: arch: samd5e5 : Oneshot, freerun and tickless available support. All support runs on Timer/Counter (TC). Some fixes in external interrupt controller (EIC) and clockconfig.

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit f5912b5cbad3b7a731231d778ccc101da6f3c353
Author: leomarradke <le...@falker.com.br>
AuthorDate: Fri Aug 14 15:23:40 2020 -0300

    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  <le...@falker.com.br>
---
 arch/arm/Kconfig                             |    1 +
 arch/arm/src/samd5e5/Kconfig                 |   72 ++
 arch/arm/src/samd5e5/hardware/sam_eic.h      |   40 +-
 arch/arm/src/samd5e5/hardware/sam_tc.h       |  479 +++++++++++
 arch/arm/src/samd5e5/sam_clockconfig.c       |  439 +++++-----
 arch/arm/src/samd5e5/sam_eic.c               |   35 +-
 arch/arm/src/samd5e5/sam_eic.h               |    2 +
 arch/arm/src/samd5e5/sam_freerun.c           |  259 ++++++
 arch/arm/src/samd5e5/sam_freerun.h           |  151 ++++
 arch/arm/src/samd5e5/sam_oneshot.c           |  459 +++++++++++
 arch/arm/src/samd5e5/sam_oneshot.h           |  212 +++++
 arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c |  336 ++++++++
 arch/arm/src/samd5e5/sam_port.h              |   15 +-
 arch/arm/src/samd5e5/sam_tc.c                | 1143 ++++++++++++++++++++++++++
 arch/arm/src/samd5e5/sam_tc.h                |  367 +++++++++
 arch/arm/src/samd5e5/sam_tickless.c          |  409 +++++++++
 arch/arm/src/samd5e5/sam_timerisr.c          |    4 +-
 boards/arm/samd5e5/metro-m4/include/board.h  |   15 +
 18 files changed, 4185 insertions(+), 253 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b55e225..cb53dd7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -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)
 
diff --git a/arch/arm/src/samd5e5/Kconfig b/arch/arm/src/samd5e5/Kconfig
index 85ae19b..f2c45b1 100644
--- a/arch/arm/src/samd5e5/Kconfig
+++ b/arch/arm/src/samd5e5/Kconfig
@@ -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"
diff --git a/arch/arm/src/samd5e5/hardware/sam_eic.h b/arch/arm/src/samd5e5/hardware/sam_eic.h
index 52fcbda..026293d 100644
--- a/arch/arm/src/samd5e5/hardware/sam_eic.h
+++ b/arch/arm/src/samd5e5/hardware/sam_eic.h
@@ -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 */
diff --git a/arch/arm/src/samd5e5/hardware/sam_tc.h b/arch/arm/src/samd5e5/hardware/sam_tc.h
new file mode 100644
index 0000000..46121e2
--- /dev/null
+++ b/arch/arm/src/samd5e5/hardware/sam_tc.h
@@ -0,0 +1,479 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/hardware/sam_tc.h
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 */
diff --git a/arch/arm/src/samd5e5/sam_clockconfig.c b/arch/arm/src/samd5e5/sam_clockconfig.c
index c795527..a27a61f 100644
--- a/arch/arm/src/samd5e5/sam_clockconfig.c
+++ b/arch/arm/src/samd5e5/sam_clockconfig.c
@@ -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);
     }
diff --git a/arch/arm/src/samd5e5/sam_eic.c b/arch/arm/src/samd5e5/sam_eic.c
index bdd0049..3a2d177 100644
--- a/arch/arm/src/samd5e5/sam_eic.c
+++ b/arch/arm/src/samd5e5/sam_eic.c
@@ -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;
 }
 
diff --git a/arch/arm/src/samd5e5/sam_eic.h b/arch/arm/src/samd5e5/sam_eic.h
index 6b32abd..be64b7e 100644
--- a/arch/arm/src/samd5e5/sam_eic.h
+++ b/arch/arm/src/samd5e5/sam_eic.h
@@ -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)
 }
diff --git a/arch/arm/src/samd5e5/sam_freerun.c b/arch/arm/src/samd5e5/sam_freerun.c
new file mode 100644
index 0000000..91d68e9
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_freerun.c
@@ -0,0 +1,259 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_freerun.c
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 */
diff --git a/arch/arm/src/samd5e5/sam_freerun.h b/arch/arm/src/samd5e5/sam_freerun.h
new file mode 100644
index 0000000..0a66d06
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_freerun.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_freerun.h
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 */
diff --git a/arch/arm/src/samd5e5/sam_oneshot.c b/arch/arm/src/samd5e5/sam_oneshot.c
new file mode 100644
index 0000000..6c0f946
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_oneshot.c
@@ -0,0 +1,459 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_oneshot.c
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 */
diff --git a/arch/arm/src/samd5e5/sam_oneshot.h b/arch/arm/src/samd5e5/sam_oneshot.h
new file mode 100644
index 0000000..6be2145
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_oneshot.h
@@ -0,0 +1,212 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_oneshot.c
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 */
diff --git a/arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c b/arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c
new file mode 100644
index 0000000..b1bda1b
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c
@@ -0,0 +1,336 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_oneshot_lowerhalf.c
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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;
+}
diff --git a/arch/arm/src/samd5e5/sam_port.h b/arch/arm/src/samd5e5/sam_port.h
index 89af653..6a34ecf 100644
--- a/arch/arm/src/samd5e5/sam_port.h
+++ b/arch/arm/src/samd5e5/sam_port.h
@@ -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:
  *
diff --git a/arch/arm/src/samd5e5/sam_tc.c b/arch/arm/src/samd5e5/sam_tc.c
new file mode 100644
index 0000000..bbd0edc
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_tc.c
@@ -0,0 +1,1143 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_tc.c
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 <errno.h>
+#include <debug.h>
+
+#include <string.h>
+#include <semaphore.h>
+#include <assert.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/wdog.h>
+#include <nuttx/clock.h>
+#include <nuttx/semaphore.h>
+
+#include "arm_internal.h"
+#include "arm_arch.h"
+
+#include "sam_gclk.h"
+#include "sam_periphclks.h"
+#include "sam_port.h"
+#include "sam_tc.h"
+
+#include "hardware/sam_pac.h"
+
+#include <arch/board/board.h>
+
+#ifdef CONFIG_SAMD5E5_TC
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Invariant attributes of an TC */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_SAMD5E5_TC0
+static const struct tc_attr_s g_tc0attr =
+{
+  .tc        = 0,
+  .irq       = SAM_IRQ_TC0,
+  .coregen   = BOARD_TC0_GCLKGEN,
+  .cc0       = BOARD_TC0_PINMAP_CC0,
+  .cc1       = BOARD_TC0_PINMAP_CC1,
+  .srcfreq   = BOARD_TC0_FREQUENCY,
+  .base      = SAM_TC0_BASE,
+};
+static struct sam_tc_dev_s g_tc0 =
+{
+  .initialized = false,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_SAMD5E5_TC1
+static const struct tc_attr_s g_tc1attr =
+{
+  .tc        = 1,
+  .irq       = SAM_IRQ_TC1,
+  .coregen   = BOARD_TC1_GCLKGEN,
+  .cc0       = BOARD_TC1_PINMAP_CC0,
+  .cc1       = BOARD_TC1_PINMAP_CC1,
+  .srcfreq   = BOARD_TC1_FREQUENCY,
+  .base      = SAM_TC1_BASE,
+};
+static struct sam_tc_dev_s g_tc1 =
+{
+  .initialized = false,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_SAMD5E5_TC2
+static const struct tc_attr_s g_tc2attr =
+{
+  .tc        = 2,
+  .irq       = SAM_IRQ_TC2,
+  .coregen   = BOARD_TC2_GCLKGEN,
+  .cc0       = BOARD_TC2_PINMAP_CC0,
+  .cc1       = BOARD_TC2_PINMAP_CC1,
+  .srcfreq   = BOARD_TC2_FREQUENCY,
+  .base      = SAM_TC2_BASE,
+};
+static struct sam_tc_dev_s g_tc2 =
+{
+  .initialized = false,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_SAMD5E5_TC3
+static const struct tc_attr_s g_tc3attr =
+{
+  .tc        = 3,
+  .irq       = SAM_IRQ_TC3,
+  .coregen   = BOARD_TC3_GCLKGEN,
+  .cc0       = BOARD_TC3_PINMAP_CC0,
+  .cc1       = BOARD_TC3_PINMAP_CC1,
+  .srcfreq   = BOARD_TC3_FREQUENCY,
+  .base      = SAM_TC3_BASE,
+};
+static struct sam_tc_dev_s g_tc3 =
+{
+  .initialized = false,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_SAMD5E5_TC4
+static const struct tc_attr_s g_tc4attr =
+{
+  .tc        = 4,
+  .irq       = SAM_IRQ_TC4,
+  .coregen   = BOARD_TC4_GCLKGEN,
+  .cc0       = BOARD_TC4_PINMAP_CC0,
+  .cc1       = BOARD_TC4_PINMAP_CC1,
+  .srcfreq   = BOARD_TC4_FREQUENCY,
+  .base      = SAM_TC4_BASE,
+};
+static struct sam_tc_dev_s g_tc4 =
+{
+  .initialized = false,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_SAMD5E5_TC5
+static const struct tc_attr_s g_tc5attr =
+{
+  .tc        = 5,
+  .irq       = SAM_IRQ_TC5,
+  .coregen   = BOARD_TC5_GCLKGEN,
+  .cc0       = BOARD_TC5_PINMAP_CC0,
+  .cc1       = BOARD_TC5_PINMAP_CC1,
+  .srcfreq   = BOARD_TC5_FREQUENCY,
+  .base      = SAM_TC5_BASE,
+};
+static struct sam_tc_dev_s g_tc5 =
+{
+  .initialized = false,
+  .inuse = false,
+};
+#endif
+
+static const uint8_t g_corclk_channel[SAMD5E5_NTC] =
+{
+    GCLK_CHAN_TC0
+  #if SAMD5E5_NTC > 1
+    , GCLK_CHAN_TC1
+  #endif
+  #if SAMD5E5_NTC > 2
+    , GCLK_CHAN_TC2
+  #endif
+  #if SAMD5E5_NTC > 3
+    , GCLK_CHAN_TC3
+  #endif
+  #if SAMD5E5_NTC > 4
+    , GCLK_CHAN_TC4
+  #endif
+  #if SAMD5E5_NTC > 5
+    , GCLK_CHAN_TC5
+  #endif
+};
+
+/* TC frequency data.
+ * This table provides the frequency for each selection of TCCLK
+ */
+
+#define TC_NDIVIDERS   8
+
+/* This is the list of divider values: divider = (1 << value) */
+
+static const uint8_t g_log2divider[TC_NDIVIDERS] =
+{
+  0,                     /* TIMER_CLOCK -> div1 */
+  1,                     /* TIMER_CLOCK -> div2 */
+  2,                     /* TIMER_CLOCK -> div4 */
+  3,                     /* TIMER_CLOCK -> div8 */
+  4,                     /* TIMER_CLOCK -> div16 */
+  6,                     /* TIMER_CLOCK -> div64 */
+  8,                     /* TIMER_CLOCK -> div256 */
+  10                     /* TIMER_CLOCK -> div1024 */
+};
+
+/* TC register lookup used by sam_tc_setregister */
+
+#define TC_NREGISTERS 2
+
+static const uint8_t g_regoffset[TC_NREGISTERS] =
+{
+  SAM_TC_COUNT32_CC0_OFFSET,     /* Channel 0 */
+  SAM_TC_COUNT32_CC1_OFFSET,     /* Channel 1 */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Initialization */
+
+static void tc_takesem(struct sam_tc_dev_s *priv);
+#define tc_givesem(priv) (nxsem_post(&priv->exclsem))
+void tc_bridge_enable(int tc);
+void sam_tc_dumpregs(struct sam_tc_dev_s *priv);
+void sam_tc_setperiod(struct sam_tc_dev_s *priv);
+
+static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tc_takesem
+ *
+ * Description:
+ *   Take the wait semaphore (handling false alarm wake-ups due to
+ *   the receipt of signals).
+ *
+ * Input Parameters:
+ *   dev - Instance of the SDIO device driver state structure.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void tc_takesem(struct sam_tc_dev_s *priv)
+{
+  int ret;
+
+  do
+    {
+      /* Take the semaphore (perhaps waiting) */
+
+      ret = nxsem_wait(&priv->exclsem);
+
+      /* The only case that an error should occur here is if the wait was
+       * awakened by a signal.
+       */
+
+      /* DEBUGASSERT(ret == OK || ret == -EINTR); */
+    }
+
+  while (ret == -EINTR);
+}
+
+/****************************************************************************
+ * Name: tc_enable
+ *
+ * Description:
+ *   Enable the Main Clock for Tc. (MCLK_APBxMASK)
+ *
+ ****************************************************************************/
+
+void tc_bridge_enable(int tc)
+{
+  DEBUGASSERT((unsigned)tc < SAMD5E5_NTC);
+
+  switch (tc)
+    {
+      case 0:
+        sam_apb_tc0_enableperiph();
+        break;
+
+      case 1:
+        sam_apb_tc1_enableperiph();
+        break;
+
+      case 2:
+        sam_apb_tc2_enableperiph();
+        break;
+
+      case 3:
+        sam_apb_tc3_enableperiph();
+        break;
+
+      case 4:
+        sam_apb_tc4_enableperiph();
+        break;
+
+      case 5:
+        sam_apb_tc5_enableperiph();
+        break;
+
+      default:
+        break;
+    }
+}
+
+/****************************************************************************
+ * Name: tc_wait_synchronization
+ *
+ * Description:
+ *   Wait until the TC reports that it is synchronized.
+ *
+ ****************************************************************************/
+
+static void tc_wait_synchronization(struct sam_tc_dev_s *priv)
+{
+  while ((getreg32(priv->attr->base +  SAM_TC_SYNCBUSY_OFFSET) & 0x7) != 0);
+}
+
+/****************************************************************************
+ * Name: tc_coreclk_configure
+ *
+ * Description:
+ *   Configure the TC source clock. PCHCTRL[id]
+ *
+ *   One generic clock is used by the TC: GCLK_TCx.
+ *
+ ****************************************************************************/
+
+void tc_coreclk_configure(int tc, int coregen, bool wrlock)
+{
+  uint8_t corechan;
+
+  DEBUGASSERT((unsigned)tc < SAMD5E5_NTC);
+
+  /* Set up the TCn_GCLK_ID_CORE clock */
+
+  corechan = g_corclk_channel[tc];
+  sam_gclk_chan_enable(corechan, coregen, wrlock);
+}
+
+/****************************************************************************
+ * Name: tc_interrupt
+ *
+ * Description:
+ *  Common timer channel interrupt handling.
+ *
+ * Input Parameters:
+ *   tc   Timer status instance
+ *
+ * Returned Value:
+ *   A pointer to the initialized timer channel structure associated with tc
+ *   and channel.  NULL is returned on any failure.
+ *
+ * On successful return, the caller holds the tc exclusive access semaphore.
+ *
+ ****************************************************************************/
+
+static int tc_interrupt(int irq, void *context, FAR void *arg)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)arg;
+  uint8_t flags;
+
+  /* Get the interrupt status for this channel */
+
+  flags = getreg8(priv->attr->base + SAM_TC_INTFLAG_OFFSET);
+  if (flags & TC_INTFLAG_OVF)
+    {
+      tmrinfo("Overflow Interrupt Flag\n");
+      putreg8(TC_INTFLAG_OVF, priv->attr->base + SAM_TC_INTFLAG_OFFSET);
+    }
+
+  if (flags & TC_INTFLAG_ERR)
+    {
+      tmrinfo("Error Interrupt Flag\n");
+      putreg8(TC_INTFLAG_ERR, priv->attr->base + SAM_TC_INTFLAG_OFFSET);
+    }
+
+  if (flags & TC_INTFLAG_MC0)
+    {
+      tmrinfo("MC0 Interrupt Flag\n");
+      putreg8(TC_INTFLAG_MC0, priv->attr->base + SAM_TC_INTFLAG_OFFSET);
+    }
+
+  if (flags & TC_INTFLAG_MC1)
+    {
+      tmrinfo("MC1 Interrupt Flag\n");
+      putreg8(TC_INTFLAG_MC1, priv->attr->base + SAM_TC_INTFLAG_OFFSET);
+    }
+
+  if (priv->handler)
+    {
+      /* Execute the callback */
+
+      priv->handler(priv, priv->arg, flags);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: sam_tc_freqdiv_lookup
+ *
+ * Description:
+ *  Given the TC input frequency (Ftcin) and a divider index, return the
+ *  value of the Ftcin divider.
+ *
+ * Input Parameters:
+ *   ftcin - TC input frequency
+ *   ndx   - Divider index
+ *
+ * Returned Value:
+ *   The Ftcin input divider value
+ *
+ ****************************************************************************/
+
+static int sam_tc_freqdiv_lookup(uint32_t ftcin, int ndx)
+{
+  /* The final option is to use the SLOW clock */
+
+  if (ndx >= TC_NDIVIDERS)
+    {
+      /* Not really a divider.  In this case, the board is actually driven
+       * by the 32.768KHz slow clock.  This returns a value that looks like
+       * correct divider if MCK were the input.
+       */
+
+      return ftcin / BOARD_OSC32K_FREQUENCY;
+    }
+  else
+    {
+      return 1 << g_log2divider[ndx];
+    }
+}
+
+/****************************************************************************
+ * Name: sam_tc_divfreq_lookup
+ *
+ * Description:
+ *  Given the TC input frequency (Ftcin) and a divider index, return the
+ *  value of the divided frequency
+ *
+ * Input Parameters:
+ *   ftcin - TC input frequency
+ *   ndx   - Divider index
+ *
+ * Returned Value:
+ *   The divided frequency value
+ *
+ ****************************************************************************/
+
+static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx)
+{
+  /* The final option is to use the SLOW clock */
+
+  if (ndx >= TC_NDIVIDERS)
+    {
+      return BOARD_OSC32K_FREQUENCY;
+    }
+  else
+    {
+      return ftcin >> g_log2divider[ndx];
+    }
+}
+
+/****************************************************************************
+ * Name: sam_tc_initialize
+ *
+ * Description:
+ *  There is no global, one-time initialization of timer/counter data
+ *  structures.  Rather, this function is called each time that a channel
+ *  is allocated and, if the channel has not been initialized, it will be
+ *  initialized then.
+ *
+ * Input Parameters:
+ *   channel TC channel number (see TC_CHANx definitions)
+ *
+ * Returned Value:
+ *   A pointer to the initialized timer channel structure associated with tc
+ *   and channel.  NULL is returned on any failure.
+ *
+ *  On successful return, the caller holds the tc exclusive access semaphore.
+ *
+ ****************************************************************************/
+
+static inline struct sam_tc_dev_s *sam_tc_initialize(int tc)
+{
+  struct sam_tc_dev_s *priv;
+
+  /* Select the timer/counter and get the index associated with the TC. */
+
+#ifdef CONFIG_SAMD5E5_TC0
+  if (tc == 0)
+    {
+      /* Select up TC0 and setup invariant attributes */
+
+      priv = &g_tc0;
+      priv->attr = &g_tc0attr;
+    }
+  else
+#endif
+#ifdef CONFIG_SAMD5E5_TC1
+  if (tc == 1)
+    {
+      /* Select up TC1 and setup invariant attributes */
+
+      priv = &g_tc1;
+      priv->attr = &g_tc1attr;
+    }
+  else
+#endif
+#ifdef CONFIG_SAMD5E5_TC2
+  if (tc == 2)
+    {
+      /* Select up TC2 and setup invariant attributes */
+
+      priv = &g_tc2;
+      priv->attr = &g_tc2attr;
+    }
+  else
+#endif
+#ifdef CONFIG_SAMD5E5_TC3
+  if (tc == 3)
+    {
+      /* Select up TC3 and setup invariant attributes */
+
+      priv = &g_tc3;
+      priv->attr = &g_tc3attr;
+    }
+  else
+#endif
+#ifdef CONFIG_SAMD5E5_TC4
+  if (tc == 4)
+    {
+      /* Select up TC4 and setup invariant attributes */
+
+      priv = &g_tc4;
+      priv->attr = &g_tc4attr;
+    }
+  else
+#endif
+#ifdef CONFIG_SAMD5E5_TC5
+  if (tc == 5)
+    {
+      /* Select up TC5 and setup invariant attributes */
+
+      priv = &g_tc5;
+      priv->attr = &g_tc5attr;
+    }
+  else
+#endif
+    {
+      tmrerr("ERROR: Unsupported TC%d\n", tc);
+      return NULL;
+    }
+
+  return priv;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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
+ *   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 tc, int frequency)
+{
+  struct sam_tc_dev_s *priv;
+  int ret;
+  uint32_t divisor;
+  uint32_t ctrla;
+  uint32_t regval;
+  irqstate_t flags;
+
+  /* Initialize the timer/counter data (if necessary) and get exclusive
+   * access to the requested tc.
+   */
+
+  tmrinfo("tc=%d frequency=%d\n", tc, frequency);
+
+  priv = sam_tc_initialize(tc);
+  if (priv)
+    {
+      /* The pre-calculate values to use when we start the timer */
+
+      ret = sam_tc_divisor(priv, frequency, &divisor, &ctrla);
+      if (ret < 0)
+        {
+          tmrerr("ERROR: sam_tc_divisor failed: %d\n", ret);
+          return NULL;
+        }
+
+      tmrinfo("frequency=%lu, divisor=%lu, ctrla=0x%08lx\n",
+          (unsigned long)frequency, (unsigned long)divisor,
+          (unsigned long)ctrla);
+
+      /* Perform one-time TC initialization */
+
+      flags = enter_critical_section();
+
+      /* Attach Interrupt Handler */
+
+      ret = irq_attach(priv->attr->irq, tc_interrupt, priv);
+      if (ret < 0)
+        {
+          tmrerr("ERROR: TC%d failed to attach irq %d\n",
+                  tc, priv->attr->irq);
+          leave_critical_section(flags);
+          return NULL;
+        }
+
+      tmrinfo("TC%d attached irq %d\n", tc, priv->attr->irq);
+
+      /* Initialize the TC driver structure */
+
+      priv->flags = 0;
+      (void)nxsem_init(&priv->exclsem, 0, 1);
+
+      /* Enable clocking to the TC module in PCHCTRL */
+
+      tc_bridge_enable(priv->attr->tc);
+      tc_bridge_enable(priv->attr->tc +1); /* Slave TC in 32 bits mode */
+
+      /* Configure the GCLKs for the TC module */
+
+      tc_coreclk_configure(priv->attr->tc, priv->attr->coregen, false);
+
+      /* Check if module is enabled */
+
+      regval = getreg32(priv->attr->base + SAM_TC_CTRLA_OFFSET);
+      if (regval & TC_CTRLA_ENABLE)
+        {
+          tmrerr("ERROR: Cannot initialize TC! It's already initialized!\n");
+          leave_critical_section(flags);
+          return NULL;
+        }
+
+      /* Check if reset is in progress */
+
+      regval = getreg32(priv->attr->base + SAM_TC_CTRLA_OFFSET);
+      if (regval & TC_CTRLA_SWRST)
+        {
+          tmrerr("ERROR: Module is in RESET process!\n");
+          leave_critical_section(flags);
+          return NULL;
+        }
+
+      /* see 48.7.1 | TC_CTRLA_PRESCSYNC_PRESC */
+
+      putreg32(ctrla | TC_CTRLA_MODE_COUNT32,
+               priv->attr->base + SAM_TC_CTRLA_OFFSET);
+      tc_wait_synchronization(priv);
+
+      /* Enable TC interrupts at the NVIC */
+
+      up_enable_irq(priv->attr->irq);
+      tmrinfo("enable TC%d irq=%d\n", tc, priv->attr->irq);
+
+      /* Get exclusive access to the timer/count data structure */
+
+      tc_takesem(priv);
+
+      /* Is it available? */
+
+      if (priv->inuse)
+        {
+          /* No.. return a failure */
+
+          tmrerr("ERROR: TC%d is in-use\n", priv->attr->tc);
+          tc_givesem(priv);
+          leave_critical_section(flags);
+          return NULL;
+        }
+
+      /* Mark the TC "inuse" */
+
+      priv->inuse = true;
+
+      /* Now the channel is initialized */
+
+      priv->initialized = true;
+
+      leave_critical_section(flags);
+      tc_givesem(priv);
+    }
+
+  /* Return an opaque reference to the tc */
+
+  tmrinfo("Returning 0x%p\n", priv);
+  return (TC_HANDLE)priv;
+}
+
+/****************************************************************************
+ * 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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+
+  tmrinfo("Freeing %p inuse=%d\n", priv, priv->inuse);
+  DEBUGASSERT(priv && priv->inuse);
+
+  /* Make sure that interrupts are detached and disabled and that the channel
+   * is stopped and disabled.
+   */
+
+  sam_tc_attach(handle, NULL, NULL, 0);
+  sam_tc_stop(handle);
+
+  /* Mark the channel as available */
+
+  priv->inuse = false;
+}
+
+/****************************************************************************
+ * 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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+  uint32_t regval;
+
+  tmrinfo("Starting TC%d inuse=%d COUNT=%d\n",
+          priv->attr->tc, priv->inuse, sam_tc_getcounter(priv));
+  DEBUGASSERT(priv && priv->inuse);
+
+  putreg32(0, priv->attr->base + SAM_TC_COUNT_OFFSET);
+
+  /* Clear any pending interrupts on this channel */
+
+  putreg8(TC_INTFLAG_ALL, priv->attr->base + SAM_TC_INTFLAG_OFFSET);
+
+  /* Then enable the timer */
+
+  regval = getreg32(priv->attr->base + SAM_TC_CTRLA_OFFSET);
+  regval |= TC_CTRLA_ENABLE;
+  putreg32(regval, priv->attr->base + SAM_TC_CTRLA_OFFSET);
+  tc_wait_synchronization(priv);
+}
+
+/****************************************************************************
+ * 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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+  uint32_t regval;
+
+  tmrinfo("Stopping TC%d inuse=%d\n", priv->attr->tc, priv->inuse);
+  DEBUGASSERT(priv && priv->inuse);
+
+  regval = getreg32(priv->attr->base + SAM_TC_CTRLA_OFFSET);
+  regval &= ~TC_CTRLA_ENABLE;
+  putreg32(regval, priv->attr->base + SAM_TC_CTRLA_OFFSET);
+  tc_wait_synchronization(priv);
+}
+
+/****************************************************************************
+ * Name: sam_tc_attach
+ *
+ * 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.
+ *   mask    The value of the timer interrupt mask register that defines
+ *           which interrupts should be disabled.
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler,
+                           void *arg, uint32_t mask)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+  tc_handler_t oldhandler;
+  irqstate_t flags;
+
+  DEBUGASSERT(priv);
+
+  /* Remember the old interrupt handler and set the new handler */
+
+  flags         = enter_critical_section();
+  oldhandler    = priv->handler;
+  priv->handler = handler;
+
+  /* Don't enable interrupt if we are detaching no matter what the caller
+   * says.
+   */
+
+  if (!handler)
+    {
+      arg  = NULL;
+      mask = 0;
+    }
+
+  priv->arg = arg;
+
+  /* Now enable interrupt as requested */
+
+  putreg8(TC_INTFLAG_ALL, priv->attr->base + SAM_TC_INTENCLR_OFFSET);
+  putreg8(mask, priv->attr->base + SAM_TC_INTENSET_OFFSET);
+  if (mask & TC_INTFLAG_MC0)
+    putreg8(TC_CTRLBSET_ONESHOT, priv->attr->base + SAM_TC_CTRLBSET_OFFSET);
+
+  leave_critical_section(flags);
+
+  return oldhandler;
+}
+
+/****************************************************************************
+ * Name: sam_tc_getpending
+ *
+ * Description:
+ *   Return the current contents of the interrupt 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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+  DEBUGASSERT(priv);
+  return getreg8(priv->attr->base + SAM_TC_INTFLAG_OFFSET);
+}
+
+/****************************************************************************
+ * 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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+
+  DEBUGASSERT(priv && regid < TC_NREGISTERS);
+
+  tmrinfo("TC%d: Set register CC%d to 0x%08lx\n",
+          priv->attr->tc, regid, (unsigned long)regval);
+
+  putreg32(regval, priv->attr->base + g_regoffset[regid]);
+}
+
+/****************************************************************************
+ * Name: sam_tc_getregister
+ *
+ * Description:
+ *    Get the current value of the channel 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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+
+  DEBUGASSERT(priv && regid < TC_NREGISTERS);
+  return getreg32(priv->attr->base + g_regoffset[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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+
+  DEBUGASSERT(priv);
+  putreg8(TC_CTRLBSET_CMD_READSYNC,
+          priv->attr->base + SAM_TC_CTRLBSET_OFFSET);
+  return getreg32(priv->attr->base + SAM_TC_COUNT_OFFSET);
+}
+
+/****************************************************************************
+ * Name: sam_tc_infreq
+ *
+ * Description:
+ *   Return the timer input frequency (Ftcin), 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)
+{
+  return BOARD_GCLK3_FREQUENCY;
+}
+
+/****************************************************************************
+ * 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)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+  uint32_t ftcin = priv->attr->srcfreq;
+  uint32_t regval;
+  int tcclks;
+
+  DEBUGASSERT(priv);
+
+  /* Get the SAM_TC_CTRLA_OFFSET register contents for this channel
+   * and extract the PRESCALER index.
+   */
+
+  regval = getreg32(priv->attr->base + SAM_TC_CTRLA_OFFSET);
+  tcclks = (regval & TC_CTRLA_PRESCALER_MASK) >> TC_CTRLA_PRESCALER_SHIFT;
+
+  /* And use the TCCLKS index to calculate the timer counter frequency */
+
+  return sam_tc_divfreq_lookup(ftcin, tcclks);
+}
+
+/****************************************************************************
+ * 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 / dev)
+ *
+ *   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 ftcin = tc->attr->srcfreq;
+  int ndx = 0;
+
+  tmrinfo("frequency=%d\n", frequency);
+
+  /* Satisfy lower bound.  That is, the value of the divider such that:
+   *
+   *   frequency >= (tc_input_frequency * 65536) / divider.
+   */
+
+  while (frequency < (sam_tc_divfreq_lookup(ftcin, ndx) >> 16))
+    {
+      if (++ndx > TC_NDIVIDERS)
+        {
+          /* If no divisor can be found, return -ERANGE */
+
+          tmrerr("ERROR: Lower bound search failed\n");
+          return -ERANGE;
+        }
+    }
+
+  /* Try to maximize DIV while still satisfying upper bound.
+   *  That the value of the divider such that:
+   *
+   *   frequency < tc_input_frequency / divider.
+   */
+
+  for (; ndx < (TC_NDIVIDERS - 1); ndx++)
+    {
+      if (frequency > sam_tc_divfreq_lookup(ftcin, ndx + 1))
+        {
+          break;
+        }
+    }
+
+  /* Return the divider value */
+
+  if (div)
+    {
+      uint32_t value = sam_tc_freqdiv_lookup(ftcin, ndx);
+      tmrinfo("return div=%lu\n", (unsigned long)value);
+      *div = value;
+    }
+
+  /* Return the PRESCALER selection */
+
+  if (tcclks)
+    {
+      tmrinfo("return tcclks=0x%08lx\n",
+             (unsigned long)TC_CTRLA_PRESCALER(ndx));
+      *tcclks = TC_CTRLA_PRESCALER(ndx);
+    }
+
+  return OK;
+}
+
+uint32_t sam_tc_getctrla(TC_HANDLE handle)
+{
+  struct sam_tc_dev_s *priv = (struct sam_tc_dev_s *)handle;
+
+  DEBUGASSERT(priv);
+  return getreg32(priv->attr->base + SAM_TC_CTRLA_OFFSET);
+}
+
+#endif /* CONFIG_SAMD5E5_TC */
diff --git a/arch/arm/src/samd5e5/sam_tc.h b/arch/arm/src/samd5e5/sam_tc.h
new file mode 100644
index 0000000..88a61f1
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_tc.h
@@ -0,0 +1,367 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_tc.h
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 */
\ No newline at end of file
diff --git a/arch/arm/src/samd5e5/sam_tickless.c b/arch/arm/src/samd5e5/sam_tickless.c
new file mode 100644
index 0000000..ed4c2aa
--- /dev/null
+++ b/arch/arm/src/samd5e5/sam_tickless.c
@@ -0,0 +1,409 @@
+/****************************************************************************
+ * arch/arm/src/samd5e5/sam_tickless.c
+ *
+ *   Copyright 2020 Falker Automacao Agricola LTDA.
+ *   Author: Leomar Mateus Radke <le...@falker.com.br>
+ *   Author: Ricardo Wartchow <wa...@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 */
diff --git a/arch/arm/src/samd5e5/sam_timerisr.c b/arch/arm/src/samd5e5/sam_timerisr.c
index 51413d7..2bd4cf3 100644
--- a/arch/arm/src/samd5e5/sam_timerisr.c
+++ b/arch/arm/src/samd5e5/sam_timerisr.c
@@ -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. */
 
diff --git a/boards/arm/samd5e5/metro-m4/include/board.h b/boards/arm/samd5e5/metro-m4/include/board.h
index 7bde7d1..0b9eec7 100644
--- a/boards/arm/samd5e5/metro-m4/include/board.h
+++ b/boards/arm/samd5e5/metro-m4/include/board.h
@@ -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 */