board.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-05-05 jg1uaa the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include "board.h"
  13. #include "drv_uart.h"
  14. #define SYSCON_BASE 0x40048000
  15. #define MEMMAP HWREG32(SYSCON_BASE + 0x000)
  16. #define SYSPLLCTRL HWREG32(SYSCON_BASE + 0x008)
  17. #define SYSPLLSTAT HWREG32(SYSCON_BASE + 0x00c)
  18. #define SYSPLLCLKSEL HWREG32(SYSCON_BASE + 0x040)
  19. #define SYSPLLCLKUEN HWREG32(SYSCON_BASE + 0x044)
  20. #define MAINCLKSEL HWREG32(SYSCON_BASE + 0x070)
  21. #define MAINCLKUEN HWREG32(SYSCON_BASE + 0x074)
  22. #define AHBCLKCTRL HWREG32(SYSCON_BASE + 0x080)
  23. #define PDRUNCFG HWREG32(SYSCON_BASE + 0x238)
  24. #define SCB_BASE 0xe000e000
  25. #define SYST_CSR HWREG32(SCB_BASE + 0x010)
  26. #define SYST_RVR HWREG32(SCB_BASE + 0x014)
  27. #define NVIC_ISER HWREG32(SCB_BASE + 0x100)
  28. #define NVIC_ICER HWREG32(SCB_BASE + 0x180)
  29. #define NVIC_ISPR HWREG32(SCB_BASE + 0x200)
  30. #define NVIC_ICPR HWREG32(SCB_BASE + 0x280)
  31. #define NVIC_IPR(irqno) HWREG32(SCB_BASE + 0x400 + (((irqno) / 4) << 2))
  32. #define SCB_SHPR3 HWREG32(SCB_BASE + 0xd20)
  33. extern unsigned char __bss_end__[];
  34. extern unsigned char _ram_end[];
  35. /**
  36. * This is the timer interrupt service routine.
  37. */
  38. void SysTick_Handler(void)
  39. {
  40. /* enter interrupt */
  41. rt_interrupt_enter();
  42. rt_tick_increase();
  43. /* leave interrupt */
  44. rt_interrupt_leave();
  45. }
  46. void os_clock_init(void)
  47. {
  48. /* bump up system clock 12MHz to 48MHz, using IRC (internal RC) osc. */
  49. MAINCLKSEL = 0; // main clock: IRC @12MHz (default, for safety)
  50. MAINCLKUEN = 0;
  51. MAINCLKUEN = 1;
  52. PDRUNCFG &= ~0x80; // power up System PLL
  53. SYSPLLCLKSEL = 0; // PLL clock source: IRC osc
  54. SYSPLLCLKUEN = 0;
  55. SYSPLLCLKUEN = 1;
  56. SYSPLLCTRL = 0x23; // Fcco = 2 x P x FCLKOUT
  57. // 192MHz = 2 x 2 x 48MHz
  58. // M = FCLKOUT / FCLKIN
  59. // 4 = 48MHz / 12MHz
  60. while (!(SYSPLLSTAT & 1)); // wait for lock PLL
  61. MAINCLKSEL = 3; // main clock: system PLL
  62. MAINCLKUEN = 0;
  63. MAINCLKUEN = 1;
  64. AHBCLKCTRL |= (1 << 16); // power up IOCON
  65. }
  66. void SysTick_init(void)
  67. {
  68. rt_uint32_t shpr3;
  69. /* set SysTick interrupt priority */
  70. shpr3 = SCB_SHPR3;
  71. shpr3 &= ~0xff000000;
  72. shpr3 |= 0x40 << 24;
  73. SCB_SHPR3 = shpr3;
  74. /* start SysTick */
  75. SYST_CSR = 0x06; // Clock source:Core, SysTick Exception:enable
  76. SYST_RVR = (CPU_CLOCK / RT_TICK_PER_SECOND) - 1;
  77. SYST_CSR = 0x07; // Counter:enable
  78. }
  79. /**
  80. * This function initializes LPC1114 SoC.
  81. */
  82. void rt_hw_board_init(void)
  83. {
  84. os_clock_init();
  85. /* init SysTick */
  86. SysTick_init();
  87. #ifdef RT_USING_HEAP
  88. /* initialize system heap */
  89. rt_system_heap_init((void *)&__bss_end__, (void *)&_ram_end);
  90. #endif
  91. /* initialize uart */
  92. rt_hw_uart_init();
  93. #ifdef RT_USING_CONSOLE
  94. /* set console device */
  95. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  96. #endif
  97. #ifdef RT_USING_COMPONENTS_INIT
  98. rt_components_board_init();
  99. #endif
  100. }
  101. /**
  102. * Enable External Interrupt
  103. */
  104. void NVIC_EnableIRQ(rt_int32_t irqno)
  105. {
  106. NVIC_ISER = 1UL << (irqno & 0x1f);
  107. }
  108. /**
  109. * Disable External Interrupt
  110. */
  111. void NVIC_DisableIRQ(rt_int32_t irqno)
  112. {
  113. NVIC_ICER = 1UL << (irqno & 0x1f);
  114. }
  115. /**
  116. * Get Pending Interrupt
  117. * Different from CMSIS implementation,
  118. * returns zero/non-zero, not zero/one.
  119. */
  120. rt_uint32_t NVIC_GetPendingIRQ(rt_int32_t irqno)
  121. {
  122. return NVIC_ISPR & (1UL << (irqno & 0x1f));
  123. }
  124. /**
  125. * Set Pending Interrupt
  126. */
  127. void NVIC_SetPendingIRQ(rt_int32_t irqno)
  128. {
  129. NVIC_ISPR = 1UL << (irqno & 0x1f);
  130. }
  131. /**
  132. * Clear Pending Interrupt
  133. */
  134. void NVIC_ClearPendingIRQ(rt_int32_t irqno)
  135. {
  136. NVIC_ICPR = 1UL << (irqno & 0x1f);
  137. }
  138. /**
  139. * Set Interrupt Priority
  140. * Different from CMSIS implementation,
  141. * this code supports only external (device specific) interrupt.
  142. */
  143. void NVIC_SetPriority(rt_int32_t irqno, rt_uint32_t priority)
  144. {
  145. rt_uint32_t shift, ipr;
  146. shift = (irqno % 4) * 8;
  147. ipr = NVIC_IPR(irqno);
  148. ipr &= ~(0xffUL << shift);
  149. ipr |= (priority & 0xff) << shift;
  150. NVIC_IPR(irqno) = ipr;
  151. }