board.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include "board.h"
  2. void lvd_init(void)
  3. {
  4. M0P_LVD->CR = (0x0<<15) | // IE, interrupt 0:off; 1:on;
  5. (0x1<<14) | // HTEN, high level trigger LVD 0:off; 1:on(means voltage lower than expected value);
  6. (0x0<<13) | // RTEN, rising edge trigger LVD 0:off; 1:on;
  7. (0x0<<12) | // FTEN, falling edge trigger LVD 0:off; 1:on;
  8. (0x7<< 9) | // Debounce_time(be effective when FLTEN=1), 0:7us; 1:14us; .... 7:28.8ms
  9. (0x1<< 8) | // FLTEN, digital filter 0:off; 1:on;
  10. (0x7<< 4) | // VTDS, 0:1.8V; 1:1.9V; 2:2.0V; 3:2.1V; 4:2.2V; 5:2.3V; 6:2.4; 7:2.5 ....;
  11. (0x0<< 2) | // SOURCE_SEL, 0:AVCC; 1:PC13; 2:PB08; 3:PB07;
  12. (0x1<< 1) | // ACT, 0:interrupt; 1:system reset;
  13. (0x0<< 0); // LVDEN, 0:off; 1:on;
  14. M0P_LVD->CR_f.LVDEN = 0x1u;
  15. }
  16. #if defined(SYSCLK_4M_MODE)
  17. uint32_t SystemCoreClock = 4000000;
  18. #elif defined(SYSCLK_8M_MODE)
  19. uint32_t SystemCoreClock = 8000000;
  20. #elif defined(SYSCLK_16M_MODE)
  21. uint32_t SystemCoreClock = 16000000;
  22. #endif
  23. void SystemInit(void)
  24. {
  25. M0P_SYSCTRL->PERI_CLKEN0 = 0x80800030u; // enable I2C clocks because it need clock for synchronous reset
  26. M0P_SYSCTRL->PERI_CLKEN1 = 0x00000000u;
  27. // reset all peripheral
  28. M0P_RESET->PERI_RESET0 = 0x40000000;
  29. M0P_RESET->PERI_RESET1 = 0x00000000;
  30. // release reset
  31. M0P_RESET->PERI_RESET0 = 0x7F7F6FFF;
  32. M0P_RESET->PERI_RESET1 = 0x00000318;
  33. // disable all peripherals clock except FLASH
  34. M0P_SYSCTRL->PERI_CLKEN0 = 0x80800000u; // restore peripheral clock to default
  35. NVIC->ICPR[0U] = 0xFFFFFFFFu; // clear all pending IRQ
  36. lvd_init();
  37. /* FPU settings ------------------------------------------------------------*/
  38. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  39. SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
  40. #endif
  41. #ifdef VECT_TAB_OFFSET
  42. SCB->VTOR = VECT_TAB_OFFSET;
  43. #else
  44. SCB->VTOR = 0x0u;
  45. #endif
  46. M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 1;
  47. // PA13:SWDIO pull-up (default SWD_USE_IO==0, PA13,PA14 is for SWD, following cfg is bypassed)
  48. // PA14:SWCLK pull-up
  49. M0P_GPIO->PADIR = 0xFFFFu; // 0:output; 1:input
  50. M0P_GPIO->PAADS = 0x0000u; // 0:digital; 1:analog
  51. M0P_GPIO->PAPU = 0x0000u; // 0:no pull; 1:pull-up
  52. M0P_GPIO->PAPD = 0xFFFFu; // 0:no pull; 1:pull-down
  53. M0P_GPIO->PBDIR = 0xFFFFu; // 0:output; 1:input
  54. M0P_GPIO->PBADS = 0x0000u; // 0:digital; 1:analog
  55. M0P_GPIO->PBPU = 0x0000u; // 0:no pull; 1:pull-up
  56. M0P_GPIO->PBPD = 0xFFFFu; // 0:no pull; 1:pull-down
  57. // PC14:XTL(used, input, digital, no-pull)
  58. // PC15:XTL(unused)
  59. M0P_GPIO->PCDIR = 0xFFFFu; // 0:output; 1:input
  60. M0P_GPIO->PCADS = 0x0000u; // 0:digital; 1:analog
  61. M0P_GPIO->PCPU = 0x0000u; // 0:no pull; 1:pull-up
  62. M0P_GPIO->PCPD = 0xBFFFu; // 0:no pull; 1:pull-down
  63. M0P_GPIO->PDDIR = 0xFFFFu; // 0:output; 1:input
  64. M0P_GPIO->PDADS = 0x0000u; // 0:digital; 1:analog
  65. M0P_GPIO->PDPU = 0x0000u; // 0:no pull; 1:pull-up
  66. M0P_GPIO->PDPD = 0xFFFFu; // 0:no pull; 1:pull-down
  67. M0P_GPIO->PEDIR = 0xFFFFu; // 0:output; 1:input
  68. M0P_GPIO->PEADS = 0x0000u; // 0:digital; 1:analog
  69. M0P_GPIO->PEPU = 0x0000u; // 0:no pull; 1:pull-up
  70. M0P_GPIO->PEPD = 0xFFFFu; // 0:no pull; 1:pull-down
  71. // PF00,PF01:XTH(unused)
  72. M0P_GPIO->PFDIR = 0xFFFFu; // 0:output; 1:input
  73. M0P_GPIO->PFADS = 0x0000u; // 0:digital; 1:analog
  74. M0P_GPIO->PFPU = 0x0000u; // 0:no pull; 1:pull-up
  75. M0P_GPIO->PFPD = 0xFFFFu; // 0:no pull; 1:pull-down
  76. M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 0;
  77. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  78. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  79. M0P_SYSCTRL->SYSCTRL1 = (0x0<<8) | // SWD_USE_IO, 0:SWD; 1:GPIO;
  80. (0x1<<6) | // LOCKUP_EN, 0:off; 1:on(invalid instruction lead to reset);
  81. (0x0<<5) | // RTC_LPW, RTC low power 0:off; 1:on(can not access RTC regiseters);
  82. (0x1<<3) | // XTL_ALWAYS_ON, 0:allow to disable XTL; 1:forbid to disable XTL;
  83. (0x1<<2) | // EXTL_EN, 0:crystal for XTL; 1:no crystal, direct XTL from PC14;
  84. (0x1<<1); // EXTH_EN, 0:crystal for XTH; 1:no crystal, direct XTH from PF00;
  85. M0P_SYSCTRL->RCL_CR = (3<<10) | // clock startup time, 0: 4 clocks; 1: 16 clocks; 2: 64 clocks; 3: 256 clocks;
  86. (*((volatile uint16_t*) (0x00100C20ul))); // TRIM, 38.4KHz
  87. // select system clock, AHB clock and APB clock
  88. // set XTL RCL ON, RCH is default ON, and keep it
  89. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  90. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  91. M0P_SYSCTRL->SYSCTRL0 = (0<<11) | // PCLK_PRS, PCLK is, 0:HCLK; 1:HCLK/2; 2:HCLK/4; 3:HCLK/8;
  92. (0<<8) | // HCLK_PRS, HCLK is, 0:SystemClk; 1:SystemClk/2; 2:Systemclk/4; .... 7:SystemClk/128;
  93. (0<<5) | // CLKSW, SystemClk is 0: RCH(default); 1: XTH; 2: RCL; 3: XTL; 4: PLL;
  94. (0<<4) | // PLL_EN, 0:OFF; 1:ON;
  95. (1<<3) | // XTL_EN, 0:OFF; 1:ON;
  96. (1<<2) | // RCL_EN, 0:OFF; 1:ON;
  97. (0<<1) | // XTH_EN, 0:OFF; 1:ON;
  98. (1<<0); // RCH_EN, 0:OFF; 1:ON; RCH must be ON at first
  99. while(!M0P_SYSCTRL->RCL_CR_f.STABLE){ // wait until RCL is ready
  100. }
  101. // 1) switch to RCL at first
  102. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  103. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  104. M0P_SYSCTRL->SYSCTRL0_f.CLKSW = 2; // switch system clock to 0: RCH; 1: XTH; 2: RCL; 3: XTL; 4: PLL;
  105. // 2) decrease Flash latency after decreasing frequency
  106. M0P_FLASH->BYPASS = 0X5A5A;
  107. M0P_FLASH->BYPASS = 0XA5A5;
  108. M0P_FLASH->CR_f.WAIT = 0; // 0:Frequency<=24MHz; 1:24MHz< Frequency<=48HHz; 2:48MHz<Frequency;
  109. // 3.0) set RCH OFF
  110. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  111. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  112. M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = 0;
  113. // 3.1) RCH = 4M or 8M or 16M
  114. #if defined(SYSCLK_4M_MODE)
  115. M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C08ul))); // 4MHz
  116. #elif defined(SYSCLK_8M_MODE)
  117. M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C06ul))); // 8MHz
  118. #elif defined(SYSCLK_16M_MODE)
  119. M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C04ul))); // 16MHz
  120. #endif
  121. // 3.2) set RCH ON
  122. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  123. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  124. M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = 1;
  125. while(!M0P_SYSCTRL->RCH_CR_f.STABLE){ // wait until RCH is ready
  126. }
  127. // 4) increase Flash latency before increasing frequency(default MSI is 4MHz after reset)
  128. M0P_FLASH->BYPASS = 0X5A5A;
  129. M0P_FLASH->BYPASS = 0XA5A5;
  130. M0P_FLASH->CR_f.WAIT = 0; // 0:Frequency<=24MHz; 1:24MHz< Frequency<=48HHz; 2:48MHz<Frequency;
  131. // 5) switch to RCH
  132. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  133. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  134. M0P_SYSCTRL->SYSCTRL0_f.CLKSW = 0; // 0: RCH; 1: XTH; 2: RCL; 3: XTL; 4: PLL;
  135. #ifndef RCL_38p4K_ENABLE
  136. // 6) set RCL OFF
  137. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  138. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  139. M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = 0;
  140. #endif
  141. }
  142. void IRQMutEnable(IRQn_Type IRQn, uint32_t Priority)
  143. {
  144. rt_base_t level;
  145. level = rt_hw_interrupt_disable();
  146. NVIC_SetPriority(IRQn, Priority); // set interrupt priority
  147. NVIC_EnableIRQ(IRQn); // enable interrrupt
  148. rt_hw_interrupt_enable(level);
  149. }
  150. /* SysTick configuration */
  151. // systick is 4194.304ms(4MHz) or 2097.152ms(8MHz) interval
  152. void systick_init(void)
  153. {
  154. // IRQMutEnable(SysTick_IRQn, IRQnPriority0);
  155. // set SYSTICK period 1ms
  156. //#if defined(SYSCLK_4M_MODE)
  157. // SysTick->LOAD = 4000000 - 1;
  158. //#elif defined(SYSCLK_8M_MODE)
  159. // SysTick->LOAD = 8000000 - 1;
  160. //#elif defined(SYSCLK_16M_MODE)
  161. // SysTick->LOAD = 16000000 - 1;
  162. //#endif
  163. SysTick->LOAD = 0x00FFFFFF;
  164. SysTick->VAL = 0UL;
  165. SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk) | // systick clksource is HCLK
  166. // (SysTick_CTRL_TICKINT_Msk) | // systick interrupt enable
  167. (SysTick_CTRL_ENABLE_Msk); // systick enable
  168. }
  169. /**
  170. * This function will delay for some us, but not release CPU.
  171. *
  172. * @param us the delay time of us, us < 4194304(4MHz) or 2097152(8MHz) or 1048576(16MHz)
  173. */
  174. void us_delay(uint32_t us)
  175. {
  176. uint32_t start, now, delta, us_tick;
  177. start = SysTick->VAL;
  178. #if defined(SYSCLK_4M_MODE)
  179. us_tick = us*4;
  180. #elif defined(SYSCLK_8M_MODE)
  181. us_tick = us*8;
  182. #elif defined(SYSCLK_16M_MODE)
  183. us_tick = us*16;
  184. #endif
  185. do {
  186. now = SysTick->VAL;
  187. delta = start > now ? start - now : 0x1000000 + start - now;
  188. } while(delta < us_tick);
  189. }
  190. uint32_t expire_systick = 0x80000000u;
  191. // SysTick-VAL is count-down every clock
  192. // [us] < 2097152(4MHz) or 1048576(8MHz)
  193. void CalExpireTime(uint32_t us)
  194. {
  195. uint32_t new_systick;
  196. uint32_t delta;
  197. #if defined(SYSCLK_4M_MODE)
  198. us *= 4;
  199. #elif defined(SYSCLK_8M_MODE)
  200. us *= 8;
  201. #elif defined(SYSCLK_16M_MODE)
  202. us *= 16;
  203. #endif
  204. new_systick = (SysTick->VAL - us) & 0xFFFFFFu;
  205. if (expire_systick&0x80000000u){
  206. expire_systick = new_systick;
  207. } else {
  208. delta = (expire_systick - new_systick) & 0xFFFFFFu;
  209. if (delta<0x800000u){
  210. expire_systick = new_systick;
  211. }
  212. }
  213. }
  214. void WaitExpireTime(void)
  215. {
  216. uint32_t delta;
  217. if (expire_systick&0x80000000u){
  218. return;
  219. }
  220. while(1){
  221. delta = (expire_systick - SysTick->VAL) & 0xFFFFFFu;
  222. if (delta<0x800000u){
  223. expire_systick = 0x80000000u;
  224. return;
  225. }
  226. }
  227. }