From dc3aa13e90f3f69223b1bb9e07b8e26f4a4ba100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Fri, 14 Apr 2017 14:22:38 +0200 Subject: [PATCH 1/2] cortexm_common: Introduce bitbanding macros --- cpu/cortexm_common/include/bit.h | 231 +++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 cpu/cortexm_common/include/bit.h diff --git a/cpu/cortexm_common/include/bit.h b/cpu/cortexm_common/include/bit.h new file mode 100644 index 0000000000..a4c34ac7d9 --- /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 + */ + +#ifndef BIT_H +#define BIT_H + +#include +#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 */ +/** @} */ From a63c0a84a69b1a11a04edfd6ae6ca67224b80d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Sat, 15 Apr 2017 14:57:02 +0200 Subject: [PATCH 2/2] kinetis: Use bit.h functions --- boards/frdm-k64f/include/periph_conf.h | 4 +- boards/mulle/include/periph_conf.h | 10 +-- boards/pba-d-01-kw2x/include/periph_conf.h | 7 +- cpu/k60/include/cpu_conf.h | 85 +--------------------- cpu/k64f/include/cpu_conf.h | 19 ++--- cpu/kinetis_common/include/periph_cpu.h | 25 +++---- cpu/kinetis_common/periph/adc.c | 9 ++- cpu/kinetis_common/periph/dac.c | 8 +- cpu/kinetis_common/periph/gpio.c | 3 +- cpu/kinetis_common/periph/timer.c | 32 ++++---- cpu/kinetis_common/periph/uart.c | 3 +- cpu/kw2xd/include/cpu_conf.h | 10 +-- 12 files changed, 67 insertions(+), 148 deletions(-) diff --git a/boards/frdm-k64f/include/periph_conf.h b/boards/frdm-k64f/include/periph_conf.h index cd74dd5c79..d15411571c 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 374597c566..b01478f794 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 fb52ee9cb9..d9b547e65e 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/k60/include/cpu_conf.h b/cpu/k60/include/cpu_conf.h index 76664982cc..081e232413 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 85656b085c..22ce06c6b4 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 d4ca43c4b9..ff993b9eb1 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 0170429cf2..9c5aba2735 100644 --- a/cpu/kinetis_common/periph/adc.c +++ b/cpu/kinetis_common/periph/adc.c @@ -25,6 +25,7 @@ #include #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 cf3eaf4998..170372e522 100644 --- a/cpu/kinetis_common/periph/dac.c +++ b/cpu/kinetis_common/periph/dac.c @@ -25,6 +25,7 @@ #include #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 001ac40ddc..11e8007636 100644 --- a/cpu/kinetis_common/periph/gpio.c +++ b/cpu/kinetis_common/periph/gpio.c @@ -27,6 +27,7 @@ #include #include #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 9179ea4bea..f0d8f853f6 100644 --- a/cpu/kinetis_common/periph/timer.c +++ b/cpu/kinetis_common/periph/timer.c @@ -26,6 +26,7 @@ #include #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 b25525aac7..cb5639e8dd 100644 --- a/cpu/kinetis_common/periph/uart.c +++ b/cpu/kinetis_common/periph/uart.c @@ -26,6 +26,7 @@ #include #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 f0b67294e8..ffaf7a3a83 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.