diff --git a/arch/arm/src/efm32/Kconfig b/arch/arm/src/efm32/Kconfig index 3509454d350..0b90826e5ed 100644 --- a/arch/arm/src/efm32/Kconfig +++ b/arch/arm/src/efm32/Kconfig @@ -150,6 +150,10 @@ config EFM32_I2C1 bool "I2C1" default n +config EFM32_BITBAND + bool "BITBAND" + default n + config EFM32_USART0 bool "USART0" default n diff --git a/arch/arm/src/efm32/Make.defs b/arch/arm/src/efm32/Make.defs index 44374cf1512..609ac46d14e 100644 --- a/arch/arm/src/efm32/Make.defs +++ b/arch/arm/src/efm32/Make.defs @@ -109,6 +109,10 @@ ifeq ($(CONFIG_EFM32_FLASHPROG),y) CHIP_CSRCS += efm32_flash.c endif +ifeq ($(CONFIG_EFM32_BITBAND),y) +CHIP_CSRCS += efm32_bitband.c +endif + ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) CHIP_CSRCS += efm32_idle.c endif diff --git a/arch/arm/src/efm32/efm32_bitband.c b/arch/arm/src/efm32/efm32_bitband.c new file mode 100644 index 00000000000..5bb1b5ecb46 --- /dev/null +++ b/arch/arm/src/efm32/efm32_bitband.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_bitband.c + * + * Copyright (C) 2014 Bouteville Pierre-Noel. All rights reserved. + * Authors: Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "stdint.h" + +#include "efm32_bitband.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_EFM32_BITBAND) + +#ifndef EFM32_BITBAND_PER_BASE +# error "EFM32_BITBAND_PER_BASE not declared bitband may be not supported?" +#endif + +#ifndef EFM32_BITBAND_RAM_BASE +# error "EFM32_BITBAND_RAM_BASE not declared bitband may be not supported?" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + +/****************************************************************************** + * Name: bitband_set_peripheral + * Perform bit-band write operation on peripheral memory location. + * + * Description + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Parameters + * addr Peripheral address location to modify bit in. + * bit Bit position to modify, 0-31. + * val Value to set bit to, 0 or 1. + * + ******************************************************************************/ +inline void bitband_set_peripheral(uint32_t addr, uint32_t bit, uint32_t val) +{ + uint32_t regval; + regval = EFM32_BITBAND_PER_BASE + ((addr-EFM32_PER_MEM_BASE)*32) + (bit*4); + + *((volatile uint32_t *)regval) = (uint32_t)val; +} + + +/****************************************************************************** + * Name: bitband_get_peripheral + * Perform bit-band operation on peripheral memory location. + * + * Description + * This function reads a single bit from the peripheral bit-band alias region. + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Parameters + * addr Peripheral address location to read. + * bit Bit position to modify, 0-31. + * + * Return bit value read, 0 or 1. + * + ******************************************************************************/ +inline uint32_t bitband_get_peripheral(uint32_t addr, uint32_t bit) +{ + uint32_t regval; + regval = EFM32_BITBAND_PER_BASE + ((addr-EFM32_PER_MEM_BASE)*32) + (bit*4); + + return *((volatile uint32_t *)regval); +} + + +/****************************************************************************** + * Name: bitband_set_sram + * Perform bit-band write operation on SRAM memory location. + * + * Description + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Parameters + * addr SRAM address location to modify bit in. + * bit Bit position to modify, 0-31. + * val Value to set bit to, 0 or 1. + * + ******************************************************************************/ +inline void bitband_set_sram(uint32_t addr, uint32_t bit, uint32_t val) +{ + uint32_t regval; + regval = EFM32_BITBAND_RAM_BASE + ((addr-EFM32_RAM_MEM_BASE)*32) + (bit*4); + + *((volatile uint32_t *)regval) = (uint32_t)val; +} + + +/****************************************************************************** + * Name: bitband_get_sram + * Perform bit-band operation on SRAM memory location. + * + * Description + * This function reads a single bit from the RAM bit-band alias region. + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Parameters + * addr Peripheral address location to read. + * bit Bit position to modify, 0-31. + * + * Return bit value read, 0 or 1. + * + ******************************************************************************/ +inline uint32_t bitband_get_sram(uint32_t addr, uint32_t bit) +{ + uint32_t regval; + regval = EFM32_BITBAND_RAM_BASE + ((addr-EFM32_RAM_MEM_BASE)*32) + (bit*4); + + return *((volatile uint32_t *)regval); +} +#endif + + diff --git a/arch/arm/src/efm32/efm32_bitband.h b/arch/arm/src/efm32/efm32_bitband.h new file mode 100644 index 00000000000..12308a11d7a --- /dev/null +++ b/arch/arm/src/efm32/efm32_bitband.h @@ -0,0 +1,81 @@ +/***************************************************************************** + * arch/arm/src/efm32/efm32_bitband.h + * + * Copyright (C) 2015 Pierre-noel Bouteville . All rights reserved. + * Authors: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_BITBAND_H +#define __ARCH_ARM_SRC_EFM32_EFM32_BITBAND_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip/efm32_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#if defined(CONFIG_EFM32_BITBAND) +inline void bitband_set_peripheral(uint32_t addr, uint32_t bit, uint32_t val); +inline uint32_t bitband_get_peripheral(uint32_t addr, uint32_t bit); +inline void bitband_set_sram(uint32_t addr, uint32_t bit, uint32_t val); +inline uint32_t bitband_get_sram(uint32_t addr, uint32_t bit); + +#else + +# define bitband_set_peripheral(addr,bit,val)\ + modifyreg32(addr,~(1<> bit) & 1) + +# define bitband_set_sram(add,bit,val)\ + modifyreg32(addr,~(1<> bit) & 1) + +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_BITBAND_H */ diff --git a/arch/arm/src/efm32/efm32_gpioirq.c b/arch/arm/src/efm32/efm32_gpioirq.c index 4dbbd009d48..1043e3dae5d 100644 --- a/arch/arm/src/efm32/efm32_gpioirq.c +++ b/arch/arm/src/efm32/efm32_gpioirq.c @@ -49,6 +49,7 @@ #include "up_arch.h" #include "chip/efm32_gpio.h" #include "efm32_gpio.h" +#include "efm32_bitband.h" #ifdef CONFIG_EFM32_GPIO_IRQ @@ -270,20 +271,24 @@ void efm32_gpioirq(gpio_pinset_t pinset) void efm32_gpioirqenable(int irq) { - irqstate_t flags; - uint32_t regval; - uint32_t bit; if (irq >= EFM32_IRQ_EXTI0 && irq <= EFM32_IRQ_EXTI15) { /* Enable the interrupt associated with the pin */ +#ifndef CONFIG_EFM32_BITBAND + irqstate_t flags; + uint32_t regval; + uint32_t bit; bit = ((uint32_t)1 << (irq - EFM32_IRQ_EXTI0)); flags = irqsave(); regval = getreg32(EFM32_GPIO_IEN); regval |= bit; putreg32(regval, EFM32_GPIO_IEN); irqrestore(flags); +#else + bitband_set_peripheral(EFM32_GPIO_IEN,(irq - EFM32_IRQ_EXTI0),1); +#endif } } @@ -297,20 +302,24 @@ void efm32_gpioirqenable(int irq) void efm32_gpioirqdisable(int irq) { - irqstate_t flags; - uint32_t regval; - uint32_t bit; if (irq >= EFM32_IRQ_EXTI0 && irq <= EFM32_IRQ_EXTI15) { /* Enable the interrupt associated with the pin */ +#ifndef CONFIG_EFM32_BITBAND + irqstate_t flags; + uint32_t regval; + uint32_t bit; bit = ((uint32_t)1 << (irq - EFM32_IRQ_EXTI0)); flags = irqsave(); regval = getreg32(EFM32_GPIO_IEN); regval &= ~bit; putreg32(regval, EFM32_GPIO_IEN); irqrestore(flags); +#else + bitband_set_peripheral(EFM32_GPIO_IEN,(irq - EFM32_IRQ_EXTI0),0); +#endif } } @@ -325,20 +334,24 @@ void efm32_gpioirqdisable(int irq) void efm32_gpioirqclear(int irq) { - irqstate_t flags; - uint32_t regval; - uint32_t bit; - if (irq >= EFM32_IRQ_EXTI0 && irq <= EFM32_IRQ_EXTI15) { /* Enable the interrupt associated with the pin */ +#ifndef CONFIG_EFM32_BITBAND + irqstate_t flags; + uint32_t regval; + uint32_t bit; + bit = ((uint32_t)1 << (irq - EFM32_IRQ_EXTI0)); flags = irqsave(); regval = getreg32(EFM32_GPIO_IFC); regval |= bit; putreg32(regval, EFM32_GPIO_IFC); irqrestore(flags); +#else + bitband_set_peripheral(EFM32_GPIO_IFC,(irq - EFM32_IRQ_EXTI0),1); +#endif } }