system_nrf52.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /* Copyright (c) 2015, Nordic Semiconductor ASA
  2. * All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * * Redistributions of source code must retain the above copyright notice, this
  8. * list of conditions and the following disclaimer.
  9. *
  10. * * Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * * Neither the name of Nordic Semiconductor ASA nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  24. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. */
  30. #include <stdint.h>
  31. #include <stdbool.h>
  32. #include "nrf.h"
  33. #include "system_nrf52.h"
  34. /*lint ++flb "Enter library region" */
  35. #define __SYSTEM_CLOCK_64M (64000000UL)
  36. static bool errata_16(void);
  37. static bool errata_31(void);
  38. static bool errata_32(void);
  39. static bool errata_36(void);
  40. static bool errata_37(void);
  41. static bool errata_57(void);
  42. static bool errata_66(void);
  43. #if defined ( __CC_ARM )
  44. uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
  45. #elif defined ( __ICCARM__ )
  46. __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
  47. #elif defined ( __GNUC__ )
  48. uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
  49. #endif
  50. void SystemCoreClockUpdate(void)
  51. {
  52. SystemCoreClock = __SYSTEM_CLOCK_64M;
  53. }
  54. void SystemInit(void)
  55. {
  56. /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document
  57. for your device located at https://infocenter.nordicsemi.com/ */
  58. if (errata_16()){
  59. *(volatile uint32_t *)0x4007C074 = 3131961357ul;
  60. }
  61. /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document
  62. for your device located at https://infocenter.nordicsemi.com/ */
  63. if (errata_31()){
  64. *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13;
  65. }
  66. /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document
  67. for your device located at https://infocenter.nordicsemi.com/ */
  68. if (errata_32()){
  69. CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
  70. }
  71. /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
  72. for your device located at https://infocenter.nordicsemi.com/ */
  73. if (errata_36()){
  74. NRF_CLOCK->EVENTS_DONE = 0;
  75. NRF_CLOCK->EVENTS_CTTO = 0;
  76. NRF_CLOCK->CTIV = 0;
  77. }
  78. /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document
  79. for your device located at https://infocenter.nordicsemi.com/ */
  80. if (errata_37()){
  81. *(volatile uint32_t *)0x400005A0 = 0x3;
  82. }
  83. /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document
  84. for your device located at https://infocenter.nordicsemi.com/ */
  85. if (errata_57()){
  86. *(volatile uint32_t *)0x40005610 = 0x00000005;
  87. *(volatile uint32_t *)0x40005688 = 0x00000001;
  88. *(volatile uint32_t *)0x40005618 = 0x00000000;
  89. *(volatile uint32_t *)0x40005614 = 0x0000003F;
  90. }
  91. /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
  92. for your device located at https://infocenter.nordicsemi.com/ */
  93. if (errata_66()){
  94. NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
  95. NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
  96. NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
  97. NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
  98. NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
  99. NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
  100. NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
  101. NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
  102. NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
  103. NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
  104. NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
  105. NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
  106. NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
  107. NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
  108. NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
  109. NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
  110. NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
  111. }
  112. /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
  113. * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
  114. * operations are not used in your code. */
  115. #if (__FPU_USED == 1)
  116. SCB->CPACR |= (3UL << 20) | (3UL << 22);
  117. __DSB();
  118. __ISB();
  119. #endif
  120. /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
  121. two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
  122. normal GPIOs. */
  123. #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
  124. if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
  125. NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
  126. while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
  127. NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
  128. while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
  129. NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
  130. while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
  131. NVIC_SystemReset();
  132. }
  133. #endif
  134. /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
  135. defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
  136. reserved for PinReset and not available as normal GPIO. */
  137. #if defined (CONFIG_GPIO_AS_PINRESET)
  138. if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
  139. ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
  140. NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
  141. while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
  142. NRF_UICR->PSELRESET[0] = 21;
  143. while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
  144. NRF_UICR->PSELRESET[1] = 21;
  145. while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
  146. NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
  147. while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
  148. NVIC_SystemReset();
  149. }
  150. #endif
  151. /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
  152. Specification to see which one). */
  153. #if defined (ENABLE_SWO)
  154. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  155. NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
  156. NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
  157. #endif
  158. /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
  159. Specification to see which ones). */
  160. #if defined (ENABLE_TRACE)
  161. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  162. NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
  163. NRF_P0->PIN_CNF[14] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
  164. NRF_P0->PIN_CNF[15] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
  165. NRF_P0->PIN_CNF[16] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
  166. NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
  167. NRF_P0->PIN_CNF[20] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
  168. #endif
  169. SystemCoreClockUpdate();
  170. }
  171. static bool errata_16(void)
  172. {
  173. if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
  174. {
  175. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
  176. {
  177. return true;
  178. }
  179. }
  180. return false;
  181. }
  182. static bool errata_31(void)
  183. {
  184. if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
  185. {
  186. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
  187. {
  188. return true;
  189. }
  190. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40)
  191. {
  192. return true;
  193. }
  194. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50)
  195. {
  196. return true;
  197. }
  198. }
  199. return false;
  200. }
  201. static bool errata_32(void)
  202. {
  203. if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
  204. {
  205. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
  206. {
  207. return true;
  208. }
  209. }
  210. return false;
  211. }
  212. static bool errata_36(void)
  213. {
  214. if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
  215. {
  216. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
  217. {
  218. return true;
  219. }
  220. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40)
  221. {
  222. return true;
  223. }
  224. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50)
  225. {
  226. return true;
  227. }
  228. }
  229. return false;
  230. }
  231. static bool errata_37(void)
  232. {
  233. if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
  234. {
  235. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
  236. {
  237. return true;
  238. }
  239. }
  240. return false;
  241. }
  242. static bool errata_57(void)
  243. {
  244. if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
  245. {
  246. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
  247. {
  248. return true;
  249. }
  250. }
  251. return false;
  252. }
  253. static bool errata_66(void)
  254. {
  255. if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
  256. {
  257. if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50)
  258. {
  259. return true;
  260. }
  261. }
  262. return false;
  263. }
  264. /*lint --flb "Leave library region" */