Nut/OS  5.0.5
API Reference
cm3.h
Go to the documentation of this file.
00001 #ifndef _ARCH_CM3_H_
00002 #define _ARCH_CM3_H_
00003 
00004 /*
00005  * Copyright (C) 2001-2006 by egnite Software GmbH. All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the copyright holders nor the names of
00017  *    contributors may be used to endorse or promote products derived
00018  *    from this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00027  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00028  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00030  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  * For additional information see http://www.ethernut.de/
00034  */
00035 
00036 /*
00037  * $Log$
00038  * Revision 1.00  2010/08/06 09:34:34  ulrichprinz
00039  * Initial version.
00040  */
00041 
00042 #include <stddef.h>
00043 #include <cfg/arch.h>
00044 #include <arch/cm3/cortexM3.h>
00045 
00046 #ifndef __ASSEMBLER__
00047 #include <dev/mweeprom.h>
00048 #endif
00049 
00050 #define ARM_MODE_USER       0x10
00051 #define ARM_MODE_FIQ        0x11
00052 #define ARM_MODE_IRQ        0x12
00053 #define ARM_MODE_SVC        0x13
00054 #define ARM_MODE_ABORT      0x17
00055 #define ARM_MODE_UNDEF      0x1B
00056 #define ARM_MODE_SYS        0x1F
00057 #define ARM_MODE_MASK       0x1F
00058 
00059 #define I_BIT               0x80
00060 #define ARM_CPSR_I_BIT      0x80
00061 #define F_BIT               0x40
00062 #define ARM_CPSR_F_BIT      0x40
00063 #define T_BIT               0x20
00064 #define ARM_CPSR_T_BIT      0x20
00065 
00066 #ifdef __GNUC__
00067 #ifndef CONST
00068 #define CONST      const
00069 #endif
00070 #ifndef INLINE
00071 #define INLINE     inline
00072 #endif
00073 #else
00074 #ifndef CONST
00075 #define CONST      const
00076 #endif
00077 #ifndef INLINE
00078 #define INLINE
00079 #endif
00080 #endif
00081 
00082 #define PSTR(p)    (p)
00083 #define PRG_RDB(p) (*((const char *)(p)))
00084 
00085 #define prog_char  const char
00086 #define PGM_P      prog_char *
00087 
00088 #define SIGNAL(x)  __attribute__((interrupt_handler)) void x(void)
00089 #define RAMFUNC __attribute__ ((long_call, section (".ramfunc")))
00090 
00091 #if !defined(__arm__) && !defined(__cplusplus)
00092 #define main       NutAppMain
00093 #endif
00094 
00095 #define strlen_P(x)             strlen((char *)(x))
00096 #define strcpy_P(x,y)           strcpy(x,(char *)(y))
00097 
00098 #define strcmp_P(x, y)          strcmp((char *)(x), (char *)(y))
00099 #define memcpy_P(x, y, z)       memcpy(x, y, z)
00100 
00101 #ifndef __ASSEMBLER__
00102 
00105 extern void *__bss_end;
00106 
00110 extern void *__stack;
00111 #endif
00112 
00113 #ifndef _NOP
00114 #ifdef __GNUC__
00115 #define _NOP() __asm__ __volatile__ ("mov r0, r0  @ _NOP")
00116 #else
00117 #define _NOP() asm("mov r0, r0")
00118 #endif
00119 #endif
00120 
00121 #define outb(_reg, _val)  (*((volatile unsigned char *)(_reg)) = (_val))
00122 #define outw(_reg, _val)  (*((volatile unsigned short *)(_reg)) = (_val))
00123 #define outr(_reg, _val)  (*((volatile unsigned int *)(_reg)) = (_val))
00124 
00125 #define inb(_reg)   (*((volatile unsigned char *)(_reg)))
00126 #define inw(_reg)   (*((volatile unsigned short *)(_reg)))
00127 #define inr(_reg)   (*((volatile unsigned int *)(_reg)))
00128 
00129 #define _BV(bit)    (1 << (bit))
00130 
00131 #define sbi(_reg, _bit)         outr(_reg, inr(_reg) | _BV(_bit))
00132 #define cbi(_reg, _bit)         outr(_reg, inr(_reg) & ~_BV(_bit))
00133 #define bit_is_set(_reg, _bit)  ((inr(_reg) & _BV(_bit)) != 0)
00134 #define bit_is_clear(_reg, _bit) ((inr(_reg) & _BV(_bit)) == 0)
00135 
00136 #if !defined (__ASSEMBLER__)
00137 #define mem_barrier() __asm__ __volatile__("":::"memory")
00138 
00139 static INLINE void mem_wr(unsigned int reg, unsigned int val)
00140 {
00141     *(volatile unsigned int *) reg = val;
00142 }
00143 
00144 static INLINE void mem_wr8(unsigned int reg, uint8_t val)
00145 {
00146     *(volatile uint8_t *) reg = val;
00147 }
00148 
00149 static INLINE void mem_wr16(unsigned int reg, uint16_t val)
00150 {
00151     *(volatile uint16_t *) reg = val;
00152 }
00153 
00154 static INLINE void mem_wr32(unsigned int reg, uint32_t val)
00155 {
00156     *(volatile uint32_t *) reg = val;
00157 }
00158 
00159 static INLINE unsigned int mem_rd(unsigned int reg)
00160 {
00161     return *(const volatile unsigned int *) reg;
00162 }
00163 
00164 static INLINE uint8_t mem_rd8(unsigned int reg)
00165 {
00166     return *(const volatile uint8_t *) reg;
00167 }
00168 
00169 static INLINE uint16_t mem_rd16(unsigned int reg)
00170 {
00171     return *(const volatile uint16_t *) reg;
00172 }
00173 
00174 static INLINE uint32_t mem_rd32(unsigned int reg)
00175 {
00176     return *(const volatile uint32_t *) reg;
00177 }
00178 
00179 static INLINE void mem_wr_mb(unsigned int reg, unsigned int val)
00180 {
00181     mem_barrier();
00182     mem_wr(reg, val);
00183 }
00184 
00185 static INLINE void mem_wr8_mb(unsigned int reg, uint8_t val)
00186 {
00187     mem_barrier();
00188     mem_wr8(reg, val);
00189 }
00190 
00191 static INLINE void mem_wr16_mb(unsigned int reg, uint16_t val)
00192 {
00193     mem_barrier();
00194     mem_wr16(reg, val);
00195 }
00196 
00197 static INLINE void mem_wr32_mb(unsigned int reg, uint32_t val)
00198 {
00199     mem_barrier();
00200     mem_wr32(reg, val);
00201 }
00202 
00203 static INLINE unsigned int mem_rd_mb(unsigned int reg)
00204 {
00205     unsigned int rc = mem_rd(reg);
00206     mem_barrier();
00207 
00208     return rc;
00209 }
00210 
00211 static INLINE uint8_t mem_rd8_mb(unsigned int reg)
00212 {
00213     uint8_t rc = mem_rd8(reg);
00214     mem_barrier();
00215 
00216     return rc;
00217 }
00218 
00219 static INLINE uint16_t mem_rd16_mb(unsigned int reg)
00220 {
00221     uint16_t rc = mem_rd16(reg);
00222     mem_barrier();
00223 
00224     return rc;
00225 }
00226 
00227 static INLINE uint32_t mem_rd32_mb(unsigned int reg)
00228 {
00229     uint32_t rc = mem_rd32(reg);
00230     mem_barrier();
00231 
00232     return rc;
00233 }
00234 
00235 #endif /* __ASSEMBLER__ */
00236 
00241 #define  _BI2(arg) (((arg) & 0x00000002) ? 1: 0)
00242 #define  _BI4(arg) (((arg) & 0x0000000c) ? ( _BI2(arg>> 2) +  2) :  _BI2(arg))
00243 #define  _BI8(arg) (((arg) & 0x000000f0) ? ( _BI4(arg>> 4) +  4) :  _BI4(arg))
00244 #define _BI16(arg) (((arg) & 0x0000ff00) ? ( _BI8(arg>> 8) +  8) :  _BI8(arg))
00245 #if defined __builtin_clz
00246 #define _BI32(arg) (31 - __builtin_clz(arg))
00247 #else
00248 #define _BI32(arg) (((arg) & 0xffff0000) ? (_BI16(arg>>16) + 16) : _BI16(arg))
00249 #endif
00250 
00257 #define CM3ADDR(base, regstruct, reg) ((base) + offsetof(regstruct, reg))
00258 
00268 #define CM3MEM(addr)   *((volatile unsigned long *)(addr))
00269 #define CM3MEM16(addr) *((volatile uint16_t *)     (addr))
00270 #define CM3MEM8(addr)  *((volatile uint8_t *)      (addr))
00271 
00272 #define CM3REG(base, regstruct, reg)   ((regstruct *)(base))->reg
00273 
00283 #define CM3BBREG(base, regstruct, reg, bit) *((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + (bit <<2)] ) )
00284 
00289 #define CM3BB_BASE(base) (volatile uint32_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))
00290 
00298 #define CM3BB_OFFSET(regstruct, reg, bit) ((offsetof(regstruct, reg) <<3) + bit)
00299 
00300 #ifdef __IMAGECRAFT__
00301 #define __attribute__(x)
00302 #endif
00303 
00304 #define _SFR_MEM8(addr)     (addr)
00305 #define _SFR_MEM16(addr)    (addr)
00306 
00307 #ifndef __ASSEMBLER__
00308 #ifdef __GNUC__
00309 #define ARM_SET_CP15_CR(val) __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0" :: "r"(val) : "cc")
00310 #define ARM_GET_CP15_CR() ( \
00311     { \
00312         unsigned int val; \
00313         __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0" : "=r"(val) :: "cc"); \
00314         val; \
00315     } \
00316 )
00317 #endif /* __GNUC__ */
00318 #endif /* __ASSEMBLER__ */
00319 
00320 #if !defined (__ASSEMBLER__) && defined(__CROSSWORKS_ARM)
00321 
00328 #define strcasecmp(s1, s2)      stricmp(s1, s2)
00329 #define strncasecmp(s1, s2, n)  strnicmp(s1, s2, n)
00330 
00331 /*
00332  * Not supported by CrossWorks, added prototypes here.
00333  */
00334 int   stricmp(const char *s1, const char *s2);
00335 int   strnicmp(const char *s1, const char *s2, size_t n);
00336 char *strdup(const char *str);
00337 
00338 /*
00339  * If "Enforce ANSI Checking" is enabled, which is
00340  * the default from the v2.x version of CrossWorks
00341  * the keyword asm will not be recognize. Therefore
00342  * the next define is needed to solve the problem.
00343  */
00344 #define asm __asm__
00345 #endif
00346 
00347 #endif /* _ARCH_CM3_H_ */