kinetis_hw.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /* kinetis_hw.c
  2. *
  3. * Copyright (C) 2006-2017 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #include "hw.h"
  22. #include "user_settings.h"
  23. #if defined(FREESCALE) && defined(K_SERIES)
  24. /**********************************************
  25. * NOTE: Customize for actual hardware
  26. **********************************************/
  27. // CPU include for Rowley CrossWorks packages
  28. // $(TargetsDir) location:
  29. // On Mac OS/X: Users/USERNAME/Library/Rowley Associates Limited/CrossWorks for ARM/packages/targets/
  30. // On Windows: C:/Users/USERNAME/Application Data/Local/Rowley Associates Limited/CrossWorks for ARM/packages/targets/
  31. // On Linux: home/USERNAME/.rowley_associates_limited/CrossWorks for ARM/v4/packages/targets/
  32. // Located in $(TargetsDir)/Kinetis/CMSIS/
  33. #ifdef FREESCALE_KSDK_BM
  34. #include "fsl_common.h"
  35. #include "fsl_debug_console.h"
  36. #include "fsl_rtc.h"
  37. #include "fsl_trng.h"
  38. #include "fsl_lpuart.h"
  39. #include "fsl_port.h"
  40. #include "clock_config.h"
  41. #else
  42. #include <MK64F12.h> // Located in $(TargetsDir)/Kinetis/CMSIS/
  43. #endif
  44. // System clock
  45. #ifdef FREESCALE_KSDK_BM
  46. #define SYS_CLK_HZ SystemCoreClock
  47. #else
  48. #define SYS_CLK_HZ 96000000ul /* Core system clock in Hz */
  49. #define SYS_CLK_DRS MCG_C4_DRST_DRS(0x03) /* DRS 0=24MHz, 1=48MHz, 2=72MHz, 3=96MHz */
  50. #define SYS_CLK_DMX MCG_C4_DMX32_MASK /* 0=Disable DMX32 (lower actual speed), MCG_C4_DMX32_MASK=Enable DMX32 */
  51. #define SYS_CLK_DIV 1 /* System clock divisor */
  52. #define BUS_CLK_DIV 2 /* Bus clock divisor */
  53. #define BUS_CLK_KHZ (SYS_CLK_HZ/BUS_CLK_DIV) /* Helper to calculate bus speed for UART */
  54. #define FLASH_CLK_DIV 4 /* Flash clock divisor */
  55. #endif
  56. // UART TX Port, Pin, Mux and Baud
  57. #ifdef FREESCALE_KSDK_BM
  58. #define UART_PORT LPUART0 /* UART Port */
  59. #define UART_TX_PORT PORTA /* UART TX Port */
  60. #define UART_TX_PIN 2U /* UART TX Pin */
  61. #define UART_TX_MUX kPORT_MuxAlt2 /* Kinetis UART pin mux */
  62. #elif defined (WOLFSSL_FRDM_K64)
  63. #define UART_PORT UART0 /* UART Port */
  64. #define UART_TX_PORT PORTB /* UART TX Port */
  65. #define UART_TX_PIN 17U /* UART TX Pin */
  66. #define UART_TX_MUX 0x3 /* Kinetis UART pin mux */
  67. #else
  68. #define UART_PORT UART4 /* UART Port */
  69. #define UART_TX_PORT PORTE /* UART TX Port */
  70. #define UART_TX_PIN 24U /* UART TX Pin */
  71. #define UART_TX_MUX 0x3 /* Kinetis UART pin mux */
  72. #endif
  73. #define UART_BAUD_RATE 115200 /* UART Baud Rate */
  74. #ifdef WOLFSSL_FRDM_K64
  75. #define UART_BAUD UART_BAUD_RATE*8
  76. #else
  77. #define UART_BAUD UART_BAUD_RATE
  78. #endif
  79. /* Note: You will also need to update the UART clock gate in hw_uart_init (SIM_SCGC1_UART5_MASK) */
  80. /* Note: TWR-K60 is UART3, PTC17 */
  81. /* Note: FRDM-K64 is UART4, PTE24 */
  82. /* Note: FRDM-K64 is UART4, PTE24 or UART0 PTB17 for OpenOCD (SIM_SCGC4_UART0_MASK)*/
  83. /* Note: TWR-K64 is UART5, PTE8 */
  84. /* Note: FRDM-K82F is LPUART0 A2, LPUART4 PTC15 */
  85. /***********************************************/
  86. // Private functions
  87. static uint32_t mDelayCyclesPerUs = 0;
  88. #define NOP_FOR_LOOP_INSTRUCTION_COUNT 6
  89. static void delay_nop(uint32_t count)
  90. {
  91. int i;
  92. for(i=0; i<count; i++) {
  93. __asm volatile("nop");
  94. }
  95. }
  96. static void hw_mcg_init(void)
  97. {
  98. #ifdef FREESCALE_KSDK_BM
  99. BOARD_BootClockHSRUN();
  100. #else
  101. /* Adjust clock dividers (core/system=div/1, bus=div/2, flex bus=div/2, flash=div/4) */
  102. SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(SYS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV2(BUS_CLK_DIV-1) |
  103. SIM_CLKDIV1_OUTDIV3(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV4(FLASH_CLK_DIV-1);
  104. /* Configure FEI internal clock speed */
  105. MCG->C4 = (SYS_CLK_DMX | SYS_CLK_DRS);
  106. while((MCG->C4 & (MCG_C4_DRST_DRS_MASK | MCG_C4_DMX32_MASK)) != (SYS_CLK_DMX | SYS_CLK_DRS));
  107. #endif
  108. }
  109. static void hw_gpio_init(void)
  110. {
  111. #ifdef FREESCALE_KSDK_BM
  112. CLOCK_EnableClock(kCLOCK_PortA);
  113. CLOCK_EnableClock(kCLOCK_PortB);
  114. CLOCK_EnableClock(kCLOCK_PortC);
  115. CLOCK_EnableClock(kCLOCK_PortD);
  116. CLOCK_EnableClock(kCLOCK_PortE);
  117. #else
  118. /* Enable clocks to all GPIO ports */
  119. SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK
  120. #ifdef SIM_SCGC5_PORTC_MASK
  121. | SIM_SCGC5_PORTC_MASK
  122. #endif
  123. #ifdef SIM_SCGC5_PORTD_MASK
  124. | SIM_SCGC5_PORTD_MASK
  125. #endif
  126. #ifdef SIM_SCGC5_PORTE_MASK
  127. | SIM_SCGC5_PORTE_MASK
  128. #endif
  129. );
  130. #if 0 /* Debug clock */
  131. /* ClockOut on PTC3 */
  132. PORTC->PCR[3] = PORT_PCR_MUX(0x05); /* Alt 5 */
  133. SIM_SOPT2 |= SIM_SOPT2_CLKOUTSEL(0); /* FlexBus CLKOUT */
  134. #endif
  135. #endif
  136. }
  137. static void hw_uart_init(void)
  138. {
  139. register uint16_t sbr, brfa;
  140. uint8_t temp;
  141. #ifdef FREESCALE_KSDK_BM
  142. PORT_SetPinMux(UART_TX_PORT, UART_TX_PIN, UART_TX_MUX);
  143. CLOCK_SetLpuartClock(1); /* MCGPLLCLK */
  144. DbgConsole_Init((uint32_t)UART_PORT, UART_BAUD, DEBUG_CONSOLE_DEVICE_TYPE_LPUART, SYS_CLK_HZ);
  145. #else
  146. #ifdef WOLFSSL_FRDM_K64
  147. /* Enable UART core clock ONLY for FRDM-K64F */
  148. SIM->SCGC4 |= SIM_SCGC4_UART0_MASK;
  149. #else
  150. /* Enable UART core clock */
  151. /* Note: Remember to update me if UART_PORT changes */
  152. SIM->SCGC1 |= SIM_SCGC1_UART4_MASK;
  153. #endif
  154. /* Configure UART TX pin */
  155. UART_TX_PORT->PCR[UART_TX_PIN] = PORT_PCR_MUX(UART_TX_MUX);
  156. /* Disable transmitter and receiver while we change settings. */
  157. UART_PORT->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK );
  158. /* Configure the UART for 8-bit mode, no parity */
  159. UART_PORT->C1 = 0;
  160. /* Calculate baud settings */
  161. sbr = (uint16_t)((BUS_CLK_KHZ * 1000)/(UART_BAUD * 16));
  162. temp = UART_PORT->BDH & ~(UART_BDH_SBR(0x1F));
  163. UART_PORT->BDH = temp | UART_BDH_SBR(((sbr & 0x1F00) >> 8));
  164. UART_PORT->BDL = (uint8_t)(sbr & UART_BDL_SBR_MASK);
  165. /* Determine if a fractional divider is needed to get closer to the baud rate */
  166. brfa = (((BUS_CLK_KHZ * 32000)/(UART_BAUD * 16)) - (sbr * 32));
  167. temp = UART_PORT->C4 & ~(UART_C4_BRFA(0x1F));
  168. UART_PORT->C4 = temp | UART_C4_BRFA(brfa);
  169. /* Enable receiver and transmitter */
  170. UART_PORT->C2 |= (UART_C2_TE_MASK | UART_C2_RE_MASK);
  171. #endif
  172. }
  173. static void hw_rtc_init(void)
  174. {
  175. /* Init nop delay */
  176. mDelayCyclesPerUs = (SYS_CLK_HZ / 1000000 / NOP_FOR_LOOP_INSTRUCTION_COUNT);
  177. /* Enable RTC clock and oscillator */
  178. SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
  179. if (RTC->SR & RTC_SR_TIF_MASK) {
  180. /* Resets the RTC registers except for the SWR bit */
  181. RTC->CR |= RTC_CR_SWR_MASK;
  182. RTC->CR &= ~RTC_CR_SWR_MASK;
  183. /* Set TSR register to 0x1 to avoid the TIF bit being set in the SR register */
  184. RTC->TSR = 1;
  185. }
  186. /* Disable RTC Interrupts */
  187. RTC->IER = 0;
  188. /* Enable OSC */
  189. if ((RTC->CR & RTC_CR_OSCE_MASK) == 0) {
  190. int i;
  191. /* Turn on */
  192. RTC->CR |= RTC_CR_OSCE_MASK;
  193. /* Wait RTC startup delay 1000 us */
  194. delay_us(1000);
  195. }
  196. /* Enable counter */
  197. RTC->SR |= RTC_SR_TCE_MASK;
  198. }
  199. static void hw_rand_init(void)
  200. {
  201. #ifdef FREESCALE_KSDK_BM
  202. trng_config_t trngConfig;
  203. TRNG_GetDefaultConfig(&trngConfig);
  204. /* Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.*/
  205. trngConfig.sampleMode = kTRNG_SampleModeVonNeumann;
  206. /* Initialize TRNG */
  207. TRNG_Init(TRNG0, &trngConfig);
  208. #else
  209. /* Enable RNG clocks */
  210. SIM->SCGC6 |= SIM_SCGC6_RNGA_MASK;
  211. SIM->SCGC3 |= SIM_SCGC3_RNGA_MASK;
  212. /* Wake up RNG to normal mode (take out of sleep) */
  213. RNG->CR &= ~RNG_CR_SLP_MASK;
  214. /* Enable High Assurance mode (Enables notification of security violations via SR[SECV]) */
  215. RNG->CR |= RNG_CR_HA_MASK;
  216. /* Enable RNG generation to RANDOUT FIFO */
  217. RNG->CR |= RNG_CR_GO_MASK;
  218. #endif
  219. }
  220. /* Public Functions */
  221. void hw_init(void)
  222. {
  223. hw_mcg_init();
  224. hw_gpio_init();
  225. hw_uart_init();
  226. hw_rtc_init();
  227. hw_rand_init();
  228. }
  229. uint32_t hw_get_time_sec(void)
  230. {
  231. /* Return RTC seconds */
  232. return RTC->TSR;
  233. }
  234. uint32_t hw_get_time_msec(void)
  235. {
  236. /* RTC TPR precision register increments every 32.768 kHz clock cycle */
  237. /* Convert with rounding crystal count (32768 or (1 << 15)) to milliseconds */
  238. return ( ((uint32_t)RTC->TPR * 1000) + ((1 << 15) / 2) ) / (1 << 15);
  239. }
  240. void hw_uart_printchar(int c)
  241. {
  242. #ifdef FREESCALE_KSDK_BM
  243. LPUART_WriteBlocking(UART_PORT, (const uint8_t*)&c, 1); /* Send the character */
  244. #else
  245. while(!(UART_PORT->S1 & UART_S1_TDRE_MASK)); /* Wait until space is available in the FIFO */
  246. UART_PORT->D = (uint8_t)c; /* Send the character */
  247. #endif
  248. }
  249. uint32_t hw_rand(void)
  250. {
  251. uint32_t rng;
  252. #ifdef FREESCALE_KSDK_BM
  253. TRNG_GetRandomData(TRNG0, &rng, sizeof(rng));
  254. #else
  255. while((RNG->SR & RNG_SR_OREG_LVL(0xF)) == 0) {}; /* Wait until FIFO has a value available */
  256. rng = RNG->OR; /* Return next value in FIFO output register */
  257. #endif
  258. return rng;
  259. }
  260. void delay_us(uint32_t microseconds)
  261. {
  262. delay_nop(mDelayCyclesPerUs * microseconds);
  263. }
  264. // Watchdog
  265. void hw_watchdog_disable(void)
  266. {
  267. WDOG->UNLOCK = 0xC520;
  268. WDOG->UNLOCK = 0xD928;
  269. WDOG->STCTRLH = WDOG_STCTRLH_ALLOWUPDATE_MASK;
  270. }
  271. // Flash configuration
  272. #define FSEC_UNSECURE 2
  273. #define FSEC_SECURE 0
  274. #define FSEC_FSLACC_DENIED 2
  275. #define FSEC_FSLACC_GRANTED 3
  276. #define FSEC_KEY_ENABLED 2
  277. #define FSEC_KEY_DISABLED 3
  278. #define FSEC_MASS_ERASE_DISABLE 2
  279. #define FSEC_MASS_ERASE_ENABLE 3
  280. struct flash_conf {
  281. uint8_t backdoor_key[8]; /* Backdoor Comparison Key */
  282. uint8_t fprot[4]; /* Program flash protection bytes */
  283. uint8_t fsec; /* Flash security byte */
  284. uint8_t fopt; /* Flash nonvolatile option byte */
  285. uint8_t feprot; /* FlexNVM: EEPROM protection byte */
  286. uint8_t fdprot; /* FlexNVM: Data flash protection byte */
  287. };
  288. const struct flash_conf flash_conf __attribute__ ((section (".flashconf"),used)) =
  289. {
  290. .backdoor_key = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  291. .fprot = { 0xFF, 0xFF, 0xFF, 0xFF },
  292. .fsec = NV_FSEC_SEC(FSEC_UNSECURE) | NV_FSEC_FSLACC(FSEC_FSLACC_GRANTED) |
  293. NV_FSEC_MEEN(FSEC_MASS_ERASE_ENABLE) | NV_FSEC_KEYEN(FSEC_KEY_DISABLED),
  294. .fopt = 0xFF,
  295. .feprot = 0xFF,
  296. .fdprot = 0xFF
  297. };
  298. #endif /* FREESCALE && K_SERIES */