| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- #ifndef _ARCH_CM3_H_
- #define _ARCH_CM3_H_
- /*
- * Copyright (C) 2001-2006 by egnite Software GmbH. All rights reserved.
- * Copyright (C) 2012-2014 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de).
- *
- * 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 of the copyright holders nor the names of
- * 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.
- *
- * For additional information see http://www.ethernut.de/
- */
- /*
- * $Log$
- * Revision 1.00 2010/08/06 09:34:34 ulrichprinz
- * Initial version.
- */
- #include <stddef.h>
- #include <cfg/arch.h>
- #include <arch/cm3/cortexM3.h>
- #ifndef __ASSEMBLER__
- #include <dev/mweeprom.h>
- #endif
- #define ARM_MODE_USER 0x10
- #define ARM_MODE_FIQ 0x11
- #define ARM_MODE_IRQ 0x12
- #define ARM_MODE_SVC 0x13
- #define ARM_MODE_ABORT 0x17
- #define ARM_MODE_UNDEF 0x1B
- #define ARM_MODE_SYS 0x1F
- #define ARM_MODE_MASK 0x1F
- #define I_BIT 0x80
- #define ARM_CPSR_I_BIT 0x80
- #define F_BIT 0x40
- #define ARM_CPSR_F_BIT 0x40
- #define T_BIT 0x20
- #define ARM_CPSR_T_BIT 0x20
- #ifdef __GNUC__
- #ifndef CONST
- #define CONST const
- #endif
- #ifndef INLINE
- #define INLINE inline
- #endif
- #else
- #ifndef CONST
- #define CONST const
- #endif
- #ifndef INLINE
- #define INLINE
- #endif
- #endif
- #define PSTR(p) (p)
- #define PRG_RDB(p) (*((const char *)(p)))
- #define prog_char const char
- #define PGM_P prog_char *
- #define SIGNAL(x) __attribute__((interrupt_handler)) void x(void)
- #if !defined(__arm__) && !defined(__cplusplus)
- #define main NutAppMain
- #endif
- #define strlen_P(x) strlen((char *)(x))
- #define strcpy_P(x,y) strcpy(x,(char *)(y))
- #define strcmp_P(x, y) strcmp((char *)(x), (char *)(y))
- #define memcpy_P(x, y, z) memcpy(x, y, z)
- #ifndef __ASSEMBLER__
- /*!
- * \brief End of uninitialised data segment. Defined in the linker script.
- */
- extern void *__bss_end;
- /*!
- * \brief Begin of the stack segment. Defined in the linker script.
- */
- extern void *__stack;
- #endif
- #ifndef _NOP
- #ifdef __GNUC__
- #define _NOP() __asm__ __volatile__ ("mov r0, r0 @ _NOP")
- #else
- #define _NOP() asm("mov r0, r0")
- #endif
- #endif
- #define outb(_reg, _val) (*((volatile unsigned char *)(_reg)) = (_val))
- #define outw(_reg, _val) (*((volatile unsigned short *)(_reg)) = (_val))
- #define outr(_reg, _val) (*((volatile unsigned int *)(_reg)) = (_val))
- #define inb(_reg) (*((volatile unsigned char *)(_reg)))
- #define inw(_reg) (*((volatile unsigned short *)(_reg)))
- #define inr(_reg) (*((volatile unsigned int *)(_reg)))
- #define _BV(bit) (1 << (bit))
- #define sbi(_reg, _bit) outr(_reg, inr(_reg) | _BV(_bit))
- #define cbi(_reg, _bit) outr(_reg, inr(_reg) & ~_BV(_bit))
- #define bit_is_set(_reg, _bit) ((inr(_reg) & _BV(_bit)) != 0)
- #define bit_is_clear(_reg, _bit) ((inr(_reg) & _BV(_bit)) == 0)
- /*!
- * \brief Get the Bit position index of the highest bit from a bit value
- *
- */
- #define _BI2(arg) (((arg) & 0x00000002) ? 1: 0)
- #define _BI4(arg) (((arg) & 0x0000000c) ? ( _BI2(arg>> 2) + 2) : _BI2(arg))
- #define _BI8(arg) (((arg) & 0x000000f0) ? ( _BI4(arg>> 4) + 4) : _BI4(arg))
- #define _BI16(arg) (((arg) & 0x0000ff00) ? ( _BI8(arg>> 8) + 8) : _BI8(arg))
- #if defined __builtin_clz
- #define _BI32(arg) (31 - __builtin_clz(arg))
- #else
- #define _BI32(arg) (((arg) & 0xffff0000) ? (_BI16(arg>>16) + 16) : _BI16(arg))
- #endif
- /*!
- * \brief Get the address of a device register by its base and the offset of the register
- * in its register structure
- *
- * CortexM specific:
- */
- #define CM3ADDR(base, regstruct, reg) ((base) + offsetof(regstruct, reg))
- /*!
- * \brief Atomic access via register address of CortexM devices.
- *
- * CortexM specific:
- * Translates a register address into a volatile single cycle
- * read or write access of the register.
- *
- * Constant base part of address allows room for compiler optimization
- */
- #define CM3MEM(addr) *((volatile unsigned long *)(addr))
- #define CM3MEM16(addr) *((volatile uint16_t *) (addr))
- #define CM3MEM8(addr) *((volatile uint8_t *) (addr))
- #define CM3REG(base, regstruct, reg) ((regstruct *)(base))->reg
- /*!
- * \brief Atomic bit access via bitband address of CortexM devices.
- *
- * CortexM specific:
- * Translates a register address into a volatile single cycle
- * read or write access of the register.
- *
- * Constant base part of address allows room for compiler optimization.
- *
- * Be sure to handle bit values >> 32!
- */
- #if defined (MCU_CM_NO_BITBAND)
- /* We can't map this macro, to lets abort compilation here if we ever use it */
- #else
- #define CM3BBREG(base, regstruct, reg, bit) *((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) )
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- #define CM3BBSET(base, regstruct, reg, bit) (*(volatile uint32_t *)((base) + offsetof(regstruct, reg) + ((bit)/32) * 4) |= (1<<((bit)%32)))
- #else
- #define CM3BBSET(base, regstruct, reg, bit) (*((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) ) = 1)
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- #define CM3BBCLR(base, regstruct, reg, bit) (*(volatile uint32_t *)((base) + offsetof(regstruct, reg) + ((bit)/32) * 4) &= ~(1<<((bit)%32)))
- #else
- #define CM3BBCLR(base, regstruct, reg, bit) (*((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) ) = 0)
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- #define CM3BBGET(base, regstruct, reg, bit) ((*(volatile uint32_t *)((base) + offsetof(regstruct, reg) + ((bit)/32) * 4) & (1<<((bit)%32))) == (1<<((bit)%32)))
- #else
- #define CM3BBGET(base, regstruct, reg, bit) (*((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) ))
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- /* We can't map this macro, to lets abort compilation here if we ever use it */
- #else
- #define CM3BBADDR(base, regstruct, reg, bit) ((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) )
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- #define CM3BBSETVAL(base, regstruct, reg, bit, value) (value)?CM3BBSET(base, regstruct, reg, bit):CM3BBCLR(base, regstruct, reg, bit)
- #else
- #define CM3BBSETVAL(base, regstruct, reg, bit, value) (*((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) ) = (value)?1:0)
- #endif
- /*!
- * \brief Get Base Address of the Bitband region belonging to Device Register structrure
- *
- */
- #if defined (MCU_CM_NO_BITBAND)
- /* Reproduce the base address for the following macros */
- #define CM3BB_BASE(base) ((volatile uint32_t *)base)
- #else
- #define CM3BB_BASE(base) (volatile uint32_t *) (((uint32_t)base & 0xF0000000) + 0x02000000 + (((uint32_t)base & 0xFFFFF)<<5))
- #endif
- /*!
- * \brief Get Offset of Bitband Bit in the (uint32_t*) Bitband Array
- *
- * CM3/4 can do immediate offset access for -255, +4095 bytes around a base. So bits in the first 32 32-bit
- * registers above the base can be reached witout loading an absolute address in a bitband access
- *
- */
- #if defined (MCU_CM_NO_BITBAND)
- /* We can't map this macro, to lets abort compilation here if we ever use it */
- #else
- #define CM3BB_OFFSET(regstruct, reg, bit) ((offsetof(regstruct, reg) <<3) + bit)
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- #define CM3BB_OFFSETSET(bb_base, regstruct, reg, flag) ((regstruct*)bb_base)->reg |= (flag)
- #else
- #define CM3BB_OFFSETSET(bb_base, regstruct, reg, flag) (((volatile uint32_t *)bb_base)[CM3BB_OFFSET(regstruct, reg, _BI32(flag))] = 1)
- /* Without bitband support set bb_base to base of register structure and use
- * ((regstruct*)bb_base)->reg |= (bit)
- */
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- #define CM3BB_OFFSETCLR(bb_base, regstruct, reg, flag) ((regstruct*)bb_base)->reg &= ~(flag)
- #else
- #define CM3BB_OFFSETCLR(bb_base, regstruct, reg, flag) (((volatile uint32_t *)bb_base)[CM3BB_OFFSET(regstruct, reg, _BI32(flag))] = 0)
- /* Without bitband support set bb_base to base of register structure and use
- * ((regstruct*)bb_base)->reg &= ~(bit)
- */
- #endif
- #if defined (MCU_CM_NO_BITBAND)
- #define CM3BB_OFFSETGET(bb_base, regstruct, reg, flag) ((((regstruct*)bb_base)->reg & (flag)) == (flag))
- #else
- #define CM3BB_OFFSETGET(bb_base, regstruct, reg, flag) (((volatile uint32_t *)bb_base)[CM3BB_OFFSET(regstruct, reg, _BI32(flag))])
- /* Without bitband support set bb_base to base of register structure and use
- * ((regstruct*)bb_base)->reg & (bit)
- */
- #endif
- #ifdef __IMAGECRAFT__
- #define __attribute__(x)
- #endif
- #define _SFR_MEM8(addr) (addr)
- #define _SFR_MEM16(addr) (addr)
- #ifndef __ASSEMBLER__
- #ifdef __GNUC__
- #define ARM_SET_CP15_CR(val) __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0" :: "r"(val) : "cc")
- #define ARM_GET_CP15_CR() ( \
- { \
- unsigned int val; \
- __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0" : "=r"(val) :: "cc"); \
- val; \
- } \
- )
- #endif /* __GNUC__ */
- #endif /* __ASSEMBLER__ */
- #if !defined (__ASSEMBLER__) && defined(__CROSSWORKS_ARM)
- /*!
- * \brief Case insensitive string comparisions.
- *
- * Not supported by CrossWorks and temporarly redirected
- * to the stricmp and strnicmp routines.
- *
- */
- #define strcasecmp(s1, s2) stricmp(s1, s2)
- #define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
- /*
- * Not supported by CrossWorks, added prototypes here.
- */
- int stricmp(const char *s1, const char *s2);
- int strnicmp(const char *s1, const char *s2, size_t n);
- char *strdup(const char *str);
- /*
- * If "Enforce ANSI Checking" is enabled, which is
- * the default from the v2.x version of CrossWorks
- * the keyword asm will not be recognize. Therefore
- * the next define is needed to solve the problem.
- */
- #define asm __asm__
- #endif
- #endif /* _ARCH_CM3_H_ */
|