mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #6916 from gebart/pr/cortexm3-bitband
cpu: Add bit manipulation macros for Cortex-M
This commit is contained in:
commit
42830d2308
@ -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
|
||||
},
|
||||
};
|
||||
|
@ -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
|
||||
},
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
};
|
||||
|
231
cpu/cortexm_common/include/bit.h
Normal file
231
cpu/cortexm_common/include/bit.h
Normal file
@ -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 */
|
||||
/** @} */
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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)]);
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user