diff --git a/boards/frdm-k64f/include/periph_conf.h b/boards/frdm-k64f/include/periph_conf.h
index cd74dd5c79dda17a14373efe85c96cff229e2594..d15411571c3a108f8449fe35b70e036585b43ce1 100644
--- a/boards/frdm-k64f/include/periph_conf.h
+++ b/boards/frdm-k64f/include/periph_conf.h
@@ -68,7 +68,6 @@ extern "C"
 #define TIMER_NUMOF             ((PIT_NUMOF) + (LPTMR_NUMOF))
 
 #define PIT_BASECLOCK           (CLOCK_BUSCLOCK)
-#define PIT_CLOCKGATE           (BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_PIT_SHIFT))
 #define PIT_ISR_0               isr_pit1
 #define PIT_ISR_1               isr_pit3
 #define LPTMR_ISR_0             isr_lptmr0
@@ -82,13 +81,14 @@ extern "C"
 static const uart_conf_t uart_config[] = {
     {
         .dev    = UART0,
-        .clken  = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT)),
         .freq   = CLOCK_CORECLOCK,
         .pin_rx = GPIO_PIN(PORT_B, 16),
         .pin_tx = GPIO_PIN(PORT_B, 17),
         .pcr_rx = PORT_PCR_MUX(3),
         .pcr_tx = PORT_PCR_MUX(3),
         .irqn   = UART0_RX_TX_IRQn,
+        .scgc_addr = &SIM->SCGC4,
+        .scgc_bit = SIM_SCGC4_UART0_SHIFT,
         .mode   = UART_MODE_8N1
     },
 };
diff --git a/boards/mulle/include/periph_conf.h b/boards/mulle/include/periph_conf.h
index 374597c5663bfd18b3d986de8defdd5cdd997500..b01478f794229048250eae4fee28c32ab380ebcf 100644
--- a/boards/mulle/include/periph_conf.h
+++ b/boards/mulle/include/periph_conf.h
@@ -78,14 +78,12 @@ extern "C"
 #define LPTMR_CONFIG { \
         { \
             .dev = LPTMR0, \
-            .clk_gate = (uint32_t volatile *)BITBAND_REGADDR(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT), \
-            .index = 0, \
+            .irqn = LPTMR0_IRQn, \
         } \
     }
 #define TIMER_NUMOF             ((PIT_NUMOF) + (LPTMR_NUMOF))
 
 #define PIT_BASECLOCK           (CLOCK_BUSCLOCK)
-#define PIT_CLOCKGATE           (BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_PIT_SHIFT))
 #define PIT_ISR_0               isr_pit1
 #define PIT_ISR_1               isr_pit3
 #define LPTMR_ISR_0             isr_lptmr0
@@ -99,24 +97,26 @@ extern "C"
 static const uart_conf_t uart_config[] = {
     {
         .dev    = UART0,
-        .clken  = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT)),
         .freq   = CLOCK_CORECLOCK,
         .pin_rx = GPIO_PIN(PORT_A, 14),
         .pin_tx = GPIO_PIN(PORT_A, 15),
         .pcr_rx = PORT_PCR_MUX(3),
         .pcr_tx = PORT_PCR_MUX(3),
         .irqn   = UART0_RX_TX_IRQn,
+        .scgc_addr = &SIM->SCGC4,
+        .scgc_bit = SIM_SCGC4_UART0_SHIFT,
         .mode   = UART_MODE_8N1
     },
     {
         .dev    = UART1,
-        .clken  = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT)),
         .freq   = CLOCK_CORECLOCK,
         .pin_rx = GPIO_PIN(PORT_C, 3),
         .pin_tx = GPIO_PIN(PORT_C, 4),
         .pcr_rx = PORT_PCR_MUX(3),
         .pcr_tx = PORT_PCR_MUX(3),
         .irqn   = UART1_RX_TX_IRQn,
+        .scgc_addr = &SIM->SCGC4,
+        .scgc_bit = SIM_SCGC4_UART1_SHIFT,
         .mode   = UART_MODE_8N1
     },
 };
diff --git a/boards/pba-d-01-kw2x/include/periph_conf.h b/boards/pba-d-01-kw2x/include/periph_conf.h
index fb52ee9cb9413bdcdbf03be09c340df7fb563e12..d9b547e65ea85bc0c55a9ff2c3072328baf88f25 100644
--- a/boards/pba-d-01-kw2x/include/periph_conf.h
+++ b/boards/pba-d-01-kw2x/include/periph_conf.h
@@ -70,7 +70,6 @@ extern "C"
 #define TIMER_NUMOF             ((PIT_NUMOF) + (LPTMR_NUMOF))
 
 #define PIT_BASECLOCK           (CLOCK_BUSCLOCK)
-#define PIT_CLOCKGATE           (BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_PIT_SHIFT))
 #define PIT_ISR_0               isr_pit1
 #define PIT_ISR_1               isr_pit3
 #define LPTMR_ISR_0             isr_lptmr0
@@ -84,24 +83,26 @@ extern "C"
 static const uart_conf_t uart_config[] = {
     {
         .dev    = UART2,
-        .clken  = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART2_SHIFT)),
         .freq   = CLOCK_BUSCLOCK,
         .pin_rx = GPIO_PIN(PORT_D, 2),
         .pin_tx = GPIO_PIN(PORT_D, 3),
         .pcr_rx = PORT_PCR_MUX(3),
         .pcr_tx = PORT_PCR_MUX(3),
         .irqn   = UART2_RX_TX_IRQn,
+        .scgc_addr = &SIM->SCGC4,
+        .scgc_bit = SIM_SCGC4_UART2_SHIFT,
         .mode   = UART_MODE_8N1
     },
     {
         .dev    = UART0,
-        .clken  = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT)),
         .freq   = CLOCK_CORECLOCK,
         .pin_rx = GPIO_PIN(PORT_D, 6),
         .pin_tx = GPIO_PIN(PORT_D, 7),
         .pcr_rx = PORT_PCR_MUX(3),
         .pcr_tx = PORT_PCR_MUX(3),
         .irqn   = UART0_RX_TX_IRQn,
+        .scgc_addr = &SIM->SCGC4,
+        .scgc_bit = SIM_SCGC4_UART0_SHIFT,
         .mode   = UART_MODE_8N1
     }
 };
diff --git a/cpu/cortexm_common/include/bit.h b/cpu/cortexm_common/include/bit.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4c34ac7d93a1deca72ff3e5ec0bdeffef214e9d
--- /dev/null
+++ b/cpu/cortexm_common/include/bit.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2017 Eistec AB
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup     cpu_cortexm_common
+ * @{
+ *
+ * @file
+ * @brief       Bit access macros for Cortex-M based CPUs
+ *
+ * @author      Joakim Nohlgård <joakim.nohlgard@eistec.se>
+ */
+
+#ifndef BIT_H
+#define BIT_H
+
+#include <stdint.h>
+#include "cpu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define BITBAND_FUNCTIONS_PROVIDED 1 if the CPU provides its own
+ * implementations for bit manipulation */
+#if !BITBAND_FUNCTIONS_PROVIDED
+
+#if DOXYGEN
+/** @brief Flag for telling if the CPU has hardware bit band support */
+#define CPU_HAS_BITBAND 1 || 0 (1 for Cortex-M3 and up, 0 for Cortex-M0)
+#endif
+
+#ifndef CPU_HAS_BITBAND
+#if (__CORTEX_M >= 3)
+#define CPU_HAS_BITBAND 1
+#else
+#define CPU_HAS_BITBAND 0
+#endif
+#endif
+
+#if CPU_HAS_BITBAND || DOXYGEN
+/* Cortex-M3 and higher provide a bitband address space for atomically accessing
+ * single bits of peripheral registers, and sometimes for RAM as well */
+/**
+ * @name Bit manipulation functions
+ * @{
+ */
+/* Generic bit band conversion routine */
+/**
+ * @brief Convert bit band region address and bit number to bit band alias address
+ *
+ * @param[in] ptr  base address in non bit banded memory
+ * @param[in] bit  bit number within the word
+ *
+ * @return Address of the bit within the bit band memory region
+ */
+static inline volatile void *bitband_addr(volatile void *ptr, uintptr_t bit)
+{
+    return (volatile void *)((((uintptr_t)ptr) & 0xF0000000ul) + 0x2000000ul +
+        ((((uintptr_t)ptr) & 0xFFFFFul) << 5) + (bit << 2));
+}
+
+/**
+ * @brief Set a single bit in the 32 bit word pointed to by @p ptr
+ *
+ * The effect is the same as for the following snippet:
+ *
+ * @code{c}
+ *   *ptr |= (1 << bit);
+ * @endcode
+ *
+ * There is a read-modify-write cycle occurring within the core, but this cycle
+ * is atomic and can not be disrupted by IRQs
+ *
+ * @param[in]  ptr pointer to target word
+ * @param[in]  bit bit number within the word
+ */
+static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
+{
+    *((volatile uint32_t *)bitband_addr(ptr, bit)) = 1;
+}
+
+/**
+ * @brief Set a single bit in the 16 bit word pointed to by @p ptr
+ *
+ * The effect is the same as for the following snippet:
+ *
+ * @code{c}
+ *   *ptr |= (1 << bit);
+ * @endcode
+ *
+ * There is a read-modify-write cycle occurring within the core, but this cycle
+ * is atomic and can not be disrupted by IRQs
+ *
+ * @param[in]  ptr pointer to target word
+ * @param[in]  bit bit number within the word
+ */
+static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
+{
+    *((volatile uint16_t *)bitband_addr(ptr, bit)) = 1;
+}
+
+/**
+ * @brief Set a single bit in the 8 bit byte pointed to by @p ptr
+ *
+ * The effect is the same as for the following snippet:
+ *
+ * @code{c}
+ *   *ptr |= (1 << bit);
+ * @endcode
+ *
+ * There is a read-modify-write cycle occurring within the core, but this cycle
+ * is atomic and can not be disrupted by IRQs
+ *
+ * @param[in]  ptr pointer to target byte
+ * @param[in]  bit bit number within the byte
+ */
+static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
+{
+    *((volatile uint8_t *)bitband_addr(ptr, bit)) = 1;
+}
+
+/**
+ * @brief Clear a single bit in the 32 bit word pointed to by @p ptr
+ *
+ * The effect is the same as for the following snippet:
+ *
+ * @code{c}
+ *   *ptr &= ~(1 << bit);
+ * @endcode
+ *
+ * There is a read-modify-write cycle occurring within the core, but this cycle
+ * is atomic and can not be disrupted by IRQs
+ *
+ * @param[in]  ptr pointer to target word
+ * @param[in]  bit bit number within the word
+ */
+static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
+{
+    *((volatile uint32_t *)bitband_addr(ptr, bit)) = 0;
+}
+
+/**
+ * @brief Clear a single bit in the 16 bit word pointed to by @p ptr
+ *
+ * The effect is the same as for the following snippet:
+ *
+ * @code{c}
+ *   *ptr &= ~(1 << bit);
+ * @endcode
+ *
+ * There is a read-modify-write cycle occurring within the core, but this cycle
+ * is atomic and can not be disrupted by IRQs
+ *
+ * @param[in]  ptr pointer to target word
+ * @param[in]  bit bit number within the word
+ */
+static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
+{
+    *((volatile uint16_t *)bitband_addr(ptr, bit)) = 0;
+}
+
+/**
+ * @brief Clear a single bit in the 8 bit byte pointed to by @p ptr
+ *
+ * The effect is the same as for the following snippet:
+ *
+ * @code{c}
+ *   *ptr &= ~(1 << bit);
+ * @endcode
+ *
+ * There is a read-modify-write cycle occurring within the core, but this cycle
+ * is atomic and can not be disrupted by IRQs
+ *
+ * @param[in]  ptr pointer to target byte
+ * @param[in]  bit bit number within the byte
+ */
+static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
+{
+    *((volatile uint8_t *)bitband_addr(ptr, bit)) = 0;
+}
+
+/** @} */
+
+#else /* CPU_HAS_BITBAND */
+/* CPU does not have bitbanding, fall back to plain C */
+static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
+{
+    *ptr |= (1 << (bit));
+}
+
+static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
+{
+    *ptr |= (1 << (bit));
+}
+
+static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
+{
+    *ptr |= (1 << (bit));
+}
+
+static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
+{
+    *ptr &= ~(1 << (bit));
+}
+
+static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
+{
+    *ptr &= ~(1 << (bit));
+}
+
+static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
+{
+    *ptr &= ~(1 << (bit));
+}
+
+#endif /* CPU_HAS_BITBAND */
+
+#endif /* !BITBAND_FUNCTIONS_PROVIDED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BIT_H */
+/** @} */
diff --git a/cpu/k60/include/cpu_conf.h b/cpu/k60/include/cpu_conf.h
index 76664982cc38d5977d5e2016a92769d5cdfa8f9d..081e232413bc9a3cb6f0dd635b0fcfe4aaa12862 100644
--- a/cpu/k60/include/cpu_conf.h
+++ b/cpu/k60/include/cpu_conf.h
@@ -68,50 +68,12 @@ extern "C"
 #define PIN_INTERRUPT_EDGE 0b1011
 /** @} */
 
-/** @name PORT module clock gates */
-/** @{ */
-#define PORTA_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT))
-#define PORTB_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT))
-#define PORTC_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT))
-#define PORTD_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT))
-#define PORTE_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT))
-/** @} */
-
 /**
- * @name Clock settings for the LPTMR0 timer
- * @{
+ * @name Timer hardware information
  */
-#define LPTIMER_DEV                      (LPTMR0) /**< LPTIMER hardware module */
-#define LPTIMER_CLKEN()                  (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 1)    /**< Enable LPTMR0 clock gate */
-#define LPTIMER_CLKDIS()                 (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 0)    /**< Disable LPTMR0 clock gate */
-#define LPTIMER_CLKSRC_MCGIRCLK          0    /**< internal reference clock (4MHz) */
-#define LPTIMER_CLKSRC_LPO               1    /**< PMC 1kHz output */
-#define LPTIMER_CLKSRC_ERCLK32K          2    /**< RTC clock 32768Hz */
-#define LPTIMER_CLKSRC_OSCERCLK          3    /**< system oscillator output, clock from RF-Part */
-
-#ifndef LPTIMER_CLKSRC
-#define LPTIMER_CLKSRC                   LPTIMER_CLKSRC_ERCLK32K    /**< default clock source */
-#endif
-
-#if (LPTIMER_CLKSRC == LPTIMER_CLKSRC_MCGIRCLK)
-#define LPTIMER_CLK_PRESCALE    1
-#define LPTIMER_SPEED           1000000
-#elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_OSCERCLK)
-#define LPTIMER_CLK_PRESCALE    1
-#define LPTIMER_SPEED           1000000
-#elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_ERCLK32K)
-#define LPTIMER_CLK_PRESCALE    0
-#define LPTIMER_SPEED           32768
-#else
-#define LPTIMER_CLK_PRESCALE    0
-#define LPTIMER_SPEED           1000
-#endif
-
-/** IRQ priority for hwtimer interrupts */
-#define LPTIMER_IRQ_PRIO          1
-/** IRQ channel for hwtimer interrupts */
-#define LPTIMER_IRQ_CHAN          LPTMR0_IRQn
-
+/** @{ */
+#define LPTMR_CLKEN()  (bit_set32(&SIM->SCGC5, SIM_SCGC5_LPTMR_SHIFT)) /**< Enable LPTMR0 clock gate */
+#define PIT_CLKEN()    (bit_set32(&SIM->SCGC6, SIM_SCGC6_PIT_SHIFT)) /**< Enable PIT clock gate */
 /** @} */
 
 /**
@@ -199,45 +161,6 @@ typedef enum llwu_wakeup_pin {
 
 /** @} */
 
-/**
- * @name Bit band macros
- * @{
- */
-/* Generic bitband conversion routine */
-/** @brief Convert bit-band region address and bit number to bit-band alias address
- *
- * @param[in] addr base address in non-bit-banded memory
- * @param[in] bit  bit number within the word
- *
- * @return Address of the bit within the bit-band memory region
- */
-#define BITBAND_ADDR(addr, bit) ((((uint32_t) (addr)) & 0xF0000000u) + 0x2000000 + ((((uint32_t) (addr)) & 0xFFFFF) << 5) + ((bit) << 2))
-
-/**
- * @brief Bitband 32 bit access to variable stored in SRAM_U
- *
- * @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
- * @note var must be declared 'volatile'
- */
-#define BITBAND_VAR32(var, bit) (*((uint32_t volatile*) BITBAND_ADDR(&(var), (bit))))
-
-/**
- * @brief Bitband 16 bit access to variable stored in SRAM_U
- *
- * @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
- * @note var must be declared 'volatile'
- */
-#define BITBAND_VAR16(var, bit) (*((uint16_t volatile*) BITBAND_ADDR(&(var), (bit))))
-
-/**
- * @brief Bitband 8 bit access to variable stored in SRAM_U
- *
- * @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
- * @note var must be declared 'volatile'
- */
-#define BITBAND_VAR8(var, bit) (*((uint8_t volatile*) BITBAND_ADDR(&(var), (bit))))
-
-/** @} */
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/k64f/include/cpu_conf.h b/cpu/k64f/include/cpu_conf.h
index 85656b085cb2d4a8003183c9c58d31cfb19c9be8..22ce06c6b40330b16fd46f51e3bca424357b7aab 100644
--- a/cpu/k64f/include/cpu_conf.h
+++ b/cpu/k64f/include/cpu_conf.h
@@ -62,22 +62,13 @@ extern "C"
 #define PIN_INTERRUPT_EDGE 0b1011
 /** @} */
 
-/** @name PORT module clock gates */
-/** @{ */
-#define PORTA_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT))
-#define PORTB_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT))
-#define PORTC_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT))
-#define PORTD_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT))
-#define PORTE_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT))
-/** @} */
-
 /**
- * @brief MCU specific Low Power Timer settings.
+ * @name Timer hardware information
  */
-#define LPTIMER_CLKSRC                   LPTIMER_CLKSRC_LPO
-#define LPTIMER_DEV                      (LPTMR0) /**< LPTIMER hardware module */
-#define LPTIMER_CLKEN()                  (SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK) /**< Enable LPTMR0 clock gate */
-#define LPTIMER_CLKDIS()                 (SIM->SCGC5 &= ~SIM_SCGC5_PTMR_MASK) /**< Disable LPTMR0 clock gate */
+/** @{ */
+#define LPTMR_CLKEN()  (bit_set32(&SIM->SCGC5, SIM_SCGC5_LPTMR_SHIFT)) /**< Enable LPTMR0 clock gate */
+#define PIT_CLKEN()    (bit_set32(&SIM->SCGC6, SIM_SCGC6_PIT_SHIFT)) /**< Enable PIT clock gate */
+/** @} */
 
 #ifdef __cplusplus
 }
diff --git a/cpu/kinetis_common/include/periph_cpu.h b/cpu/kinetis_common/include/periph_cpu.h
index 650c514d7888cc4405317b54a3b0c6f60034e6df..30094b06062a2e0cd595238b79038a5fa9981994 100644
--- a/cpu/kinetis_common/include/periph_cpu.h
+++ b/cpu/kinetis_common/include/periph_cpu.h
@@ -261,10 +261,8 @@ typedef struct {
 typedef struct {
     /** LPTMR device base pointer */
     LPTMR_Type *dev;
-    /** Pointer to module clock gate bit in bitband region, use BITBAND_REGADDR() */
-    uint32_t volatile *clk_gate;
-    /** LPTMR device index */
-    uint8_t index;
+    /** IRQn interrupt number */
+    uint8_t irqn;
 } lptmr_conf_t;
 
 /**
@@ -314,15 +312,16 @@ enum {
  * @brief UART module configuration options
  */
 typedef struct {
-    UART_Type *dev;             /**< Pointer to module hardware registers */
-    volatile uint32_t *clken;   /**< Clock enable bitband register address */
-    uint32_t freq;              /**< Module clock frequency, usually CLOCK_CORECLOCK or CLOCK_BUSCLOCK */
-    gpio_t pin_rx;              /**< RX pin, GPIO_UNDEF disables RX */
-    gpio_t pin_tx;              /**< TX pin */
-    uint32_t pcr_rx;            /**< Pin configuration register bits for RX */
-    uint32_t pcr_tx;            /**< Pin configuration register bits for TX */
-    IRQn_Type irqn;             /**< IRQ number for this module */
-    uint8_t mode;               /**< UART mode: data bits, parity, stop bits */
+    UART_Type *dev;               /**< Pointer to module hardware registers */
+    uint32_t freq;                /**< Module clock frequency, usually CLOCK_CORECLOCK or CLOCK_BUSCLOCK */
+    gpio_t pin_rx;                /**< RX pin, GPIO_UNDEF disables RX */
+    gpio_t pin_tx;                /**< TX pin */
+    uint32_t pcr_rx;              /**< Pin configuration register bits for RX */
+    uint32_t pcr_tx;              /**< Pin configuration register bits for TX */
+    IRQn_Type irqn;               /**< IRQ number for this module */
+    volatile uint32_t *scgc_addr; /**< Clock enable register, in SIM module */
+    uint8_t scgc_bit;             /**< Clock enable bit, within the register */
+    uint8_t mode;                 /**< UART mode: data bits, parity, stop bits */
 } uart_conf_t;
 
 /**
diff --git a/cpu/kinetis_common/periph/adc.c b/cpu/kinetis_common/periph/adc.c
index 0170429cf2b60c510a555f5e296be6b3d783b71b..9c5aba2735075a8eaabf0671a5da80ad926edbac 100644
--- a/cpu/kinetis_common/periph/adc.c
+++ b/cpu/kinetis_common/periph/adc.c
@@ -25,6 +25,7 @@
 #include <stdio.h>
 
 #include "cpu.h"
+#include "bit.h"
 #include "mutex.h"
 #include "periph/adc.h"
 
@@ -65,11 +66,11 @@ static inline int dev_num(adc_t line)
 static inline void prep(adc_t line)
 {
     if (dev(line) == ADC0) {
-        BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_ADC0_SHIFT) = 1;
+        bit_set32(&SIM->SCGC6, SIM_SCGC6_ADC0_SHIFT);
     }
 #ifdef ADC1
     else {
-        BITBAND_REG32(SIM->SCGC3, SIM_SCGC3_ADC1_SHIFT) = 1;
+        bit_set32(&SIM->SCGC3, SIM_SCGC3_ADC1_SHIFT);
     }
 #endif
     mutex_lock(&locks[dev_num(line)]);
@@ -78,11 +79,11 @@ static inline void prep(adc_t line)
 static inline void done(adc_t line)
 {
     if (dev(line) == ADC0) {
-        BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_ADC0_SHIFT) = 0;
+        bit_clear32(&SIM->SCGC6, SIM_SCGC6_ADC0_SHIFT);
     }
 #ifdef ADC1
     else {
-        BITBAND_REG32(SIM->SCGC3, SIM_SCGC3_ADC1_SHIFT) = 0;
+        bit_clear32(&SIM->SCGC3, SIM_SCGC3_ADC1_SHIFT);
     }
 #endif
     mutex_unlock(&locks[dev_num(line)]);
diff --git a/cpu/kinetis_common/periph/dac.c b/cpu/kinetis_common/periph/dac.c
index cf3eaf499830fc35d4cdaaf6f07116e9beda4f33..170372e522ee47174ab26709d774a218e5115437 100644
--- a/cpu/kinetis_common/periph/dac.c
+++ b/cpu/kinetis_common/periph/dac.c
@@ -25,6 +25,7 @@
 #include <stdint.h>
 
 #include "cpu.h"
+#include "bit.h"
 #include "periph/dac.h"
 #include "periph_conf.h"
 
@@ -84,7 +85,12 @@ static inline void _dac_set_power(dac_t line, uint8_t value)
 
     dac = dac_config[line].dev;
 
-    BITBAND_REG8(dac->C0, DAC_C0_DACEN_SHIFT) = value;
+    if (value) {
+        bit_set8(&dac->C0, DAC_C0_DACEN_SHIFT);
+    }
+    else {
+        bit_clear8(&dac->C0, DAC_C0_DACEN_SHIFT);
+    }
 }
 
 void dac_poweron(dac_t line)
diff --git a/cpu/kinetis_common/periph/gpio.c b/cpu/kinetis_common/periph/gpio.c
index 001ac40ddc8df7f3a01ed3d2ceb36384c65fb6fe..11e80076368cb57d80b98cb8b1883104244ff58f 100644
--- a/cpu/kinetis_common/periph/gpio.c
+++ b/cpu/kinetis_common/periph/gpio.c
@@ -27,6 +27,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include "cpu.h"
+#include "bit.h"
 #include "periph/gpio.h"
 
 /**
@@ -129,7 +130,7 @@ static inline int pin_num(gpio_t pin)
 
 static inline void clk_en(gpio_t pin)
 {
-    BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT + port_num(pin)) = 1;
+    bit_set32(&SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT + port_num(pin));
 }
 
 /**
diff --git a/cpu/kinetis_common/periph/timer.c b/cpu/kinetis_common/periph/timer.c
index 9179ea4bea291ad76b8d50bbf9f5aa39f1d9eb8b..f0d8f853f69ef8b4a9342c7aad3317a28c64016e 100644
--- a/cpu/kinetis_common/periph/timer.c
+++ b/cpu/kinetis_common/periph/timer.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 
 #include "cpu.h"
+#include "bit.h"
 #include "board.h"
 #include "periph_conf.h"
 #include "periph/timer.h"
@@ -87,11 +88,6 @@ static const lptmr_conf_t lptmr_config[LPTMR_NUMOF] = LPTMR_CONFIG;
 static pit_t pit[PIT_NUMOF];
 static lptmr_t lptmr[LPTMR_NUMOF];
 
-/**
- * @brief  lvalue accessor for PIT channel enable bit in the bitband region
- */
-#define PIT_BITBAND_TEN(ch) (BITBAND_REG32(PIT->CHANNEL[ch].TCTRL, PIT_TCTRL_TEN_SHIFT))
-
 /**
  * @brief  Find out whether a given timer is a LPTMR or a PIT timer
  */
@@ -174,7 +170,8 @@ inline static void _pit_set_counter(uint8_t dev)
 
 inline static int pit_init(uint8_t dev, uint32_t freq, timer_cb_t cb, void *arg)
 {
-    PIT_CLOCKGATE = 1;
+    /* Turn on module clock gate */
+    PIT_CLKEN();
     /* Completely disable the module before messing with the settings */
     PIT->MCR = PIT_MCR_MDIS_MASK;
 
@@ -215,7 +212,7 @@ inline static int pit_set(uint8_t dev, uint32_t timeout)
     pit[dev].tctrl = PIT_TCTRL_TIE_MASK | PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
     /* Add the new timeout offset to the up-counter */
     pit[dev].count += timeout;
-    if (PIT_BITBAND_TEN(ch) != 0) {
+    if ((PIT->CHANNEL[ch].TCTRL & PIT_TCTRL_TEN_MASK) != 0) {
         /* Timer is currently running */
         uint32_t cval = PIT->CHANNEL[ch].CVAL;
         /* Subtract if there was anything left on the counter */
@@ -237,7 +234,7 @@ inline static int pit_set_absolute(uint8_t dev, uint32_t target)
     pit[dev].tctrl = PIT_TCTRL_TIE_MASK | PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
     /* Set the new target time in the up-counter */
     pit[dev].count = target;
-    if (PIT_BITBAND_TEN(ch) != 0) {
+    if ((PIT->CHANNEL[ch].TCTRL & PIT_TCTRL_TEN_MASK) != 0) {
         _pit_set_counter(dev);
     }
 
@@ -255,7 +252,7 @@ inline static int pit_clear(uint8_t dev)
     pit[dev].tctrl = PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
     /* pit[dev].count += PIT_MAX_VALUE + 1; */ /* == 0 (mod 2**32) */
 
-    if (PIT_BITBAND_TEN(ch) != 0) {
+    if ((PIT->CHANNEL[ch].TCTRL & PIT_TCTRL_TEN_MASK) != 0) {
         /* Timer is currently running */
         uint32_t cval = PIT->CHANNEL[ch].CVAL;
         /* Subtract if there was anything left on the counter */
@@ -271,7 +268,7 @@ inline static int pit_clear(uint8_t dev)
 inline static uint32_t pit_read(uint8_t dev)
 {
     uint8_t ch = pit_config[dev].count_ch;
-    if (PIT_BITBAND_TEN(ch) != 0) {
+    if ((PIT->CHANNEL[ch].TCTRL & PIT_TCTRL_TEN_MASK) != 0) {
         /* Timer running */
         return pit[dev].count - PIT->CHANNEL[ch].CVAL;
     }
@@ -284,7 +281,7 @@ inline static uint32_t pit_read(uint8_t dev)
 inline static void pit_start(uint8_t dev)
 {
     uint8_t ch = pit_config[dev].count_ch;
-    if (PIT_BITBAND_TEN(ch) != 0) {
+    if ((PIT->CHANNEL[ch].TCTRL & PIT_TCTRL_TEN_MASK) != 0) {
         /* Already running */
         return;
     }
@@ -296,7 +293,7 @@ inline static void pit_start(uint8_t dev)
 inline static void pit_stop(uint8_t dev)
 {
     uint8_t ch = pit_config[dev].count_ch;
-    if (PIT_BITBAND_TEN(ch) == 0) {
+    if ((PIT->CHANNEL[ch].TCTRL & PIT_TCTRL_TEN_MASK) == 0) {
         /* Already stopped */
         return;
     }
@@ -438,7 +435,7 @@ inline static int lptmr_init(uint8_t dev, uint32_t freq, timer_cb_t cb, void *ar
     unsigned int mask = irq_disable();
 
     /* Turn on module clock */
-    *lptmr_config[dev].clk_gate = 1;
+    LPTMR_CLKEN();
     /* Completely disable the module before messing with the settings */
     hw->CSR = 0;
     /* select ERCLK32K as clock source for LPTMR */
@@ -447,9 +444,8 @@ inline static int lptmr_init(uint8_t dev, uint32_t freq, timer_cb_t cb, void *ar
     /* Clear IRQ flag in case it was already set */
     hw->CSR = LPTMR_CSR_TCF_MASK;
     /* Enable IRQs on the counting channel */
-    /* Refactor the below lines if there are any CPUs where the LPTMR IRQs are not sequential */
-    NVIC_ClearPendingIRQ(LPTMR0_IRQn + lptmr_config[dev].index);
-    NVIC_EnableIRQ(LPTMR0_IRQn + lptmr_config[dev].index);
+    NVIC_ClearPendingIRQ(lptmr_config[dev].irqn);
+    NVIC_EnableIRQ(lptmr_config[dev].irqn);
 
     _lptmr_set_cb_config(dev, cb, arg);
 
@@ -549,7 +545,7 @@ inline static void lptmr_stop(uint8_t dev)
     /* Disable counter and clear interrupt flag */
     hw->CSR = LPTMR_CSR_TCF_MASK;
     /* Clear any pending IRQ */
-    NVIC_ClearPendingIRQ(LPTMR0_IRQn + lptmr_config[dev].index);
+    NVIC_ClearPendingIRQ(lptmr_config[dev].irqn);
     irq_restore(mask);
 }
 
@@ -566,7 +562,7 @@ inline static void lptmr_irq_handler(tim_t tim)
     }
 
     /* Clear interrupt flag */
-    BITBAND_REG32(hw->CSR, LPTMR_CSR_TCF_SHIFT) = 1;
+    bit_set32(&hw->CSR, LPTMR_CSR_TCF_SHIFT);
 
     cortexm_isr_end();
 }
diff --git a/cpu/kinetis_common/periph/uart.c b/cpu/kinetis_common/periph/uart.c
index b25525aac7035240a338ac035963797c534edf0d..cb5639e8dd9764fee8f31b87251154a63baec6d8 100644
--- a/cpu/kinetis_common/periph/uart.c
+++ b/cpu/kinetis_common/periph/uart.c
@@ -26,6 +26,7 @@
 #include <math.h>
 
 #include "cpu.h"
+#include "bit.h"
 #include "periph_conf.h"
 #include "periph/uart.h"
 
@@ -93,7 +94,7 @@ static int init_base(uart_t uart, uint32_t baudrate)
     }
 
     /* Turn on module clock gate */
-    *(uart_config[uart].clken) = 1;
+    bit_set32(uart_config[uart].scgc_addr, uart_config[uart].scgc_bit);
 
     /* disable transmitter and receiver */
     dev->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK);
diff --git a/cpu/kw2xd/include/cpu_conf.h b/cpu/kw2xd/include/cpu_conf.h
index f0b67294e831a1e0035fbf1d3c51f9163c72bb9f..ffaf7a3a83ba9bdd18f454a8589098b383e9d67e 100644
--- a/cpu/kw2xd/include/cpu_conf.h
+++ b/cpu/kw2xd/include/cpu_conf.h
@@ -77,12 +77,12 @@ extern "C"
 /** @} */
 
 /**
- * @brief MCU specific Low Power Timer settings.
+ * @name Timer hardware information
  */
-#define LPTIMER_CLKSRC                   LPTIMER_CLKSRC_LPO
-#define LPTIMER_DEV                      (LPTMR0) /**< LPTIMER hardware module */
-#define LPTIMER_CLKEN()                  (SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK) /**< Enable LPTMR0 clock gate */
-#define LPTIMER_CLKDIS()                 (SIM->SCGC5 &= ~SIM_SCGC5_PTMR_MASK) /**< Disable LPTMR0 clock gate */
+/** @{ */
+#define LPTMR_CLKEN()  (bit_set32(&SIM->SCGC5, SIM_SCGC5_LPTMR_SHIFT)) /**< Enable LPTMR0 clock gate */
+#define PIT_CLKEN()    (bit_set32(&SIM->SCGC6, SIM_SCGC6_PIT_SHIFT)) /**< Enable PIT clock gate */
+/** @} */
 
 /**
  * @name KW2XD SiP internal interconnects between MCU and Modem.