cm3.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. #ifndef _ARCH_CM3_H_
  2. #define _ARCH_CM3_H_
  3. /*
  4. * Copyright (C) 2001-2006 by egnite Software GmbH. All rights reserved.
  5. * Copyright (C) 2012-2014 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de).
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the copyright holders nor the names of
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  30. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * For additional information see http://www.ethernut.de/
  34. */
  35. /*
  36. * $Log$
  37. * Revision 1.00 2010/08/06 09:34:34 ulrichprinz
  38. * Initial version.
  39. */
  40. #include <stddef.h>
  41. #include <cfg/arch.h>
  42. #include <arch/cm3/cortexM3.h>
  43. #ifndef __ASSEMBLER__
  44. #include <dev/mweeprom.h>
  45. #endif
  46. #define ARM_MODE_USER 0x10
  47. #define ARM_MODE_FIQ 0x11
  48. #define ARM_MODE_IRQ 0x12
  49. #define ARM_MODE_SVC 0x13
  50. #define ARM_MODE_ABORT 0x17
  51. #define ARM_MODE_UNDEF 0x1B
  52. #define ARM_MODE_SYS 0x1F
  53. #define ARM_MODE_MASK 0x1F
  54. #define I_BIT 0x80
  55. #define ARM_CPSR_I_BIT 0x80
  56. #define F_BIT 0x40
  57. #define ARM_CPSR_F_BIT 0x40
  58. #define T_BIT 0x20
  59. #define ARM_CPSR_T_BIT 0x20
  60. #ifdef __GNUC__
  61. #ifndef CONST
  62. #define CONST const
  63. #endif
  64. #ifndef INLINE
  65. #define INLINE inline
  66. #endif
  67. #else
  68. #ifndef CONST
  69. #define CONST const
  70. #endif
  71. #ifndef INLINE
  72. #define INLINE
  73. #endif
  74. #endif
  75. #define PSTR(p) (p)
  76. #define PRG_RDB(p) (*((const char *)(p)))
  77. #define prog_char const char
  78. #define PGM_P prog_char *
  79. #define SIGNAL(x) __attribute__((interrupt_handler)) void x(void)
  80. #if !defined(__arm__) && !defined(__cplusplus)
  81. #define main NutAppMain
  82. #endif
  83. #define strlen_P(x) strlen((char *)(x))
  84. #define strcpy_P(x,y) strcpy(x,(char *)(y))
  85. #define strcmp_P(x, y) strcmp((char *)(x), (char *)(y))
  86. #define memcpy_P(x, y, z) memcpy(x, y, z)
  87. #ifndef __ASSEMBLER__
  88. /*!
  89. * \brief End of uninitialised data segment. Defined in the linker script.
  90. */
  91. extern void *__bss_end;
  92. /*!
  93. * \brief Begin of the stack segment. Defined in the linker script.
  94. */
  95. extern void *__stack;
  96. #endif
  97. #ifndef _NOP
  98. #ifdef __GNUC__
  99. #define _NOP() __asm__ __volatile__ ("mov r0, r0 @ _NOP")
  100. #else
  101. #define _NOP() asm("mov r0, r0")
  102. #endif
  103. #endif
  104. #define outb(_reg, _val) (*((volatile unsigned char *)(_reg)) = (_val))
  105. #define outw(_reg, _val) (*((volatile unsigned short *)(_reg)) = (_val))
  106. #define outr(_reg, _val) (*((volatile unsigned int *)(_reg)) = (_val))
  107. #define inb(_reg) (*((volatile unsigned char *)(_reg)))
  108. #define inw(_reg) (*((volatile unsigned short *)(_reg)))
  109. #define inr(_reg) (*((volatile unsigned int *)(_reg)))
  110. #define _BV(bit) (1 << (bit))
  111. #define sbi(_reg, _bit) outr(_reg, inr(_reg) | _BV(_bit))
  112. #define cbi(_reg, _bit) outr(_reg, inr(_reg) & ~_BV(_bit))
  113. #define bit_is_set(_reg, _bit) ((inr(_reg) & _BV(_bit)) != 0)
  114. #define bit_is_clear(_reg, _bit) ((inr(_reg) & _BV(_bit)) == 0)
  115. /*!
  116. * \brief Get the Bit position index of the highest bit from a bit value
  117. *
  118. */
  119. #define _BI2(arg) (((arg) & 0x00000002) ? 1: 0)
  120. #define _BI4(arg) (((arg) & 0x0000000c) ? ( _BI2(arg>> 2) + 2) : _BI2(arg))
  121. #define _BI8(arg) (((arg) & 0x000000f0) ? ( _BI4(arg>> 4) + 4) : _BI4(arg))
  122. #define _BI16(arg) (((arg) & 0x0000ff00) ? ( _BI8(arg>> 8) + 8) : _BI8(arg))
  123. #if defined __builtin_clz
  124. #define _BI32(arg) (31 - __builtin_clz(arg))
  125. #else
  126. #define _BI32(arg) (((arg) & 0xffff0000) ? (_BI16(arg>>16) + 16) : _BI16(arg))
  127. #endif
  128. /*!
  129. * \brief Get the address of a device register by its base and the offset of the register
  130. * in its register structure
  131. *
  132. * CortexM specific:
  133. */
  134. #define CM3ADDR(base, regstruct, reg) ((base) + offsetof(regstruct, reg))
  135. /*!
  136. * \brief Atomic access via register address of CortexM devices.
  137. *
  138. * CortexM specific:
  139. * Translates a register address into a volatile single cycle
  140. * read or write access of the register.
  141. *
  142. * Constant base part of address allows room for compiler optimization
  143. */
  144. #define CM3MEM(addr) *((volatile unsigned long *)(addr))
  145. #define CM3MEM16(addr) *((volatile uint16_t *) (addr))
  146. #define CM3MEM8(addr) *((volatile uint8_t *) (addr))
  147. #define CM3REG(base, regstruct, reg) ((regstruct *)(base))->reg
  148. /*!
  149. * \brief Atomic bit access via bitband address of CortexM devices.
  150. *
  151. * CortexM specific:
  152. * Translates a register address into a volatile single cycle
  153. * read or write access of the register.
  154. *
  155. * Constant base part of address allows room for compiler optimization.
  156. *
  157. * Be sure to handle bit values >> 32!
  158. */
  159. #if defined (MCU_CM_NO_BITBAND)
  160. /* We can't map this macro, to lets abort compilation here if we ever use it */
  161. #else
  162. #define CM3BBREG(base, regstruct, reg, bit) *((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) )
  163. #endif
  164. #if defined (MCU_CM_NO_BITBAND)
  165. #define CM3BBSET(base, regstruct, reg, bit) (*(volatile uint32_t *)((base) + offsetof(regstruct, reg) + ((bit)/32) * 4) |= (1<<((bit)%32)))
  166. #else
  167. #define CM3BBSET(base, regstruct, reg, bit) (*((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) ) = 1)
  168. #endif
  169. #if defined (MCU_CM_NO_BITBAND)
  170. #define CM3BBCLR(base, regstruct, reg, bit) (*(volatile uint32_t *)((base) + offsetof(regstruct, reg) + ((bit)/32) * 4) &= ~(1<<((bit)%32)))
  171. #else
  172. #define CM3BBCLR(base, regstruct, reg, bit) (*((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) ) = 0)
  173. #endif
  174. #if defined (MCU_CM_NO_BITBAND)
  175. #define CM3BBGET(base, regstruct, reg, bit) ((*(volatile uint32_t *)((base) + offsetof(regstruct, reg) + ((bit)/32) * 4) & (1<<((bit)%32))) == (1<<((bit)%32)))
  176. #else
  177. #define CM3BBGET(base, regstruct, reg, bit) (*((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) ))
  178. #endif
  179. #if defined (MCU_CM_NO_BITBAND)
  180. /* We can't map this macro, to lets abort compilation here if we ever use it */
  181. #else
  182. #define CM3BBADDR(base, regstruct, reg, bit) ((volatile uint32_t *) &(((uint8_t *) ((base & 0xF0000000) + 0x02000000 + ((base & 0xFFFFF)<<5))) [(offsetof(regstruct, reg) <<5) + ((bit) <<2)] ) )
  183. #endif
  184. #if defined (MCU_CM_NO_BITBAND)
  185. #define CM3BBSETVAL(base, regstruct, reg, bit, value) (value)?CM3BBSET(base, regstruct, reg, bit):CM3BBCLR(base, regstruct, reg, bit)
  186. #else
  187. #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)
  188. #endif
  189. /*!
  190. * \brief Get Base Address of the Bitband region belonging to Device Register structrure
  191. *
  192. */
  193. #if defined (MCU_CM_NO_BITBAND)
  194. /* Reproduce the base address for the following macros */
  195. #define CM3BB_BASE(base) ((volatile uint32_t *)base)
  196. #else
  197. #define CM3BB_BASE(base) (volatile uint32_t *) (((uint32_t)base & 0xF0000000) + 0x02000000 + (((uint32_t)base & 0xFFFFF)<<5))
  198. #endif
  199. /*!
  200. * \brief Get Offset of Bitband Bit in the (uint32_t*) Bitband Array
  201. *
  202. * CM3/4 can do immediate offset access for -255, +4095 bytes around a base. So bits in the first 32 32-bit
  203. * registers above the base can be reached witout loading an absolute address in a bitband access
  204. *
  205. */
  206. #if defined (MCU_CM_NO_BITBAND)
  207. /* We can't map this macro, to lets abort compilation here if we ever use it */
  208. #else
  209. #define CM3BB_OFFSET(regstruct, reg, bit) ((offsetof(regstruct, reg) <<3) + bit)
  210. #endif
  211. #if defined (MCU_CM_NO_BITBAND)
  212. #define CM3BB_OFFSETSET(bb_base, regstruct, reg, flag) ((regstruct*)bb_base)->reg |= (flag)
  213. #else
  214. #define CM3BB_OFFSETSET(bb_base, regstruct, reg, flag) (((volatile uint32_t *)bb_base)[CM3BB_OFFSET(regstruct, reg, _BI32(flag))] = 1)
  215. /* Without bitband support set bb_base to base of register structure and use
  216. * ((regstruct*)bb_base)->reg |= (bit)
  217. */
  218. #endif
  219. #if defined (MCU_CM_NO_BITBAND)
  220. #define CM3BB_OFFSETCLR(bb_base, regstruct, reg, flag) ((regstruct*)bb_base)->reg &= ~(flag)
  221. #else
  222. #define CM3BB_OFFSETCLR(bb_base, regstruct, reg, flag) (((volatile uint32_t *)bb_base)[CM3BB_OFFSET(regstruct, reg, _BI32(flag))] = 0)
  223. /* Without bitband support set bb_base to base of register structure and use
  224. * ((regstruct*)bb_base)->reg &= ~(bit)
  225. */
  226. #endif
  227. #if defined (MCU_CM_NO_BITBAND)
  228. #define CM3BB_OFFSETGET(bb_base, regstruct, reg, flag) ((((regstruct*)bb_base)->reg & (flag)) == (flag))
  229. #else
  230. #define CM3BB_OFFSETGET(bb_base, regstruct, reg, flag) (((volatile uint32_t *)bb_base)[CM3BB_OFFSET(regstruct, reg, _BI32(flag))])
  231. /* Without bitband support set bb_base to base of register structure and use
  232. * ((regstruct*)bb_base)->reg & (bit)
  233. */
  234. #endif
  235. #ifdef __IMAGECRAFT__
  236. #define __attribute__(x)
  237. #endif
  238. #define _SFR_MEM8(addr) (addr)
  239. #define _SFR_MEM16(addr) (addr)
  240. #ifndef __ASSEMBLER__
  241. #ifdef __GNUC__
  242. #define ARM_SET_CP15_CR(val) __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0" :: "r"(val) : "cc")
  243. #define ARM_GET_CP15_CR() ( \
  244. { \
  245. unsigned int val; \
  246. __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0" : "=r"(val) :: "cc"); \
  247. val; \
  248. } \
  249. )
  250. #endif /* __GNUC__ */
  251. #endif /* __ASSEMBLER__ */
  252. #if !defined (__ASSEMBLER__) && defined(__CROSSWORKS_ARM)
  253. /*!
  254. * \brief Case insensitive string comparisions.
  255. *
  256. * Not supported by CrossWorks and temporarly redirected
  257. * to the stricmp and strnicmp routines.
  258. *
  259. */
  260. #define strcasecmp(s1, s2) stricmp(s1, s2)
  261. #define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
  262. /*
  263. * Not supported by CrossWorks, added prototypes here.
  264. */
  265. int stricmp(const char *s1, const char *s2);
  266. int strnicmp(const char *s1, const char *s2, size_t n);
  267. char *strdup(const char *str);
  268. /*
  269. * If "Enforce ANSI Checking" is enabled, which is
  270. * the default from the v2.x version of CrossWorks
  271. * the keyword asm will not be recognize. Therefore
  272. * the next define is needed to solve the problem.
  273. */
  274. #define asm __asm__
  275. #endif
  276. #endif /* _ARCH_CM3_H_ */