board_drv.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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->PBDIR = 0xFFFFu; // PB07 输入
  68. M0P_GPIO->PBADS = 0x0000u; // PB07 数字模式
  69. M0P_GPIO->PBPU = 0x0000u; // PB07 不上拉
  70. M0P_GPIO->PBPD = 0xFFFFu; // PB07 下拉
  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. // HC32L19x support 4 levels priority only
  86. //NVIC_SetPriorityGrouping(5); // 5:2 preemption-priority bits + 2 sub-priority bits; 3:4+0; 7:0+4;
  87. // default clock is RCH, not modify RCH until switch to RCL
  88. // XTL=32.768KHz PC14 from MS1030 TSTO1
  89. // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 1;
  90. // M0P_GPIO->PCADS |= 0xC000U; // analog
  91. // M0P_GPIO->PCPU &= 0x3FFFu; // 0:no pull; 1:pull-up
  92. // M0P_GPIO->PCPD &= 0x3FFFu; // 0:no pull; 1:pull-down
  93. // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 0;
  94. // M0P_SYSCTRL->XTL_CR = (3<<4) | // STARTUP, startup clocks, 0:256; 1:1024; 2:4096; 3:16384;
  95. // (2<<2) | // AMP_SEL, 0~3
  96. // (3<<0); // DRIVER, 0~3
  97. // no XTH PF00 PF01
  98. // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 1;
  99. // M0P_GPIO->PFDIR |= 0x0003U; // input
  100. // M0P_GPIO->PFADS &= 0xFFFCU; // digital
  101. // M0P_GPIO->PFPU &= 0xFFFCu; // 0:no pull; 1:pull-up
  102. // M0P_GPIO->PFPD |= 0x0003u; // 0:no pull; 1:pull-down
  103. // M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 0;
  104. // M0P_SYSCTRL->XTH_CR = (3<<4) | // STARTUP, startup clocks, 0:256; 1:1024; 2:4096; 3:16384;
  105. // (0<<2) | // XTH_FSEL, 0:4M~8M; 1:8M~16M; 2:16M~24M; 3:24M~32M;
  106. // (0<<0); // DRIVER, 0~3
  107. // RCL = 38.4K
  108. M0P_SYSCTRL->RCL_CR = (3<<10) | // clock startup time, 0: 4 clocks; 1: 16 clocks; 2: 64 clocks; 3: 256 clocks;
  109. (*((volatile uint16_t*) (0x00100C20ul))); // TRIM, 38.4KHz
  110. // (*((volatile uint16_t*) (0x00100C22ul))); // TRIM, 32.768KHz
  111. // select system clock, AHB clock and APB clock
  112. // set XTL RCL ON, RCH is default ON, and keep it
  113. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  114. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  115. M0P_SYSCTRL->SYSCTRL0 = (0<<11) | // PCLK_PRS, PCLK is, 0:HCLK; 1:HCLK/2; 2:HCLK/4; 3:HCLK/8;
  116. (0<<8) | // HCLK_PRS, HCLK is, 0:SystemClk; 1:SystemClk/2; 2:Systemclk/4; .... 7:SystemClk/128;
  117. (0<<5) | // CLKSW, SystemClk is 0: RCH(default); 1: XTH; 2: RCL; 3: XTL; 4: PLL;
  118. (0<<4) | // PLL_EN, 0:OFF; 1:ON;
  119. (1<<3) | // XTL_EN, 0:OFF; 1:ON;
  120. (1<<2) | // RCL_EN, 0:OFF; 1:ON;
  121. (0<<1) | // XTH_EN, 0:OFF; 1:ON;
  122. (1<<0); // RCH_EN, 0:OFF; 1:ON; RCH must be ON at first
  123. while(!M0P_SYSCTRL->RCL_CR_f.STABLE){ // wait until RCL is ready
  124. }
  125. // 1) switch to RCL at first
  126. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  127. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  128. M0P_SYSCTRL->SYSCTRL0_f.CLKSW = 2; // switch system clock to 0: RCH; 1: XTH; 2: RCL; 3: XTL; 4: PLL;
  129. // 2) decrease Flash latency after decreasing frequency
  130. M0P_FLASH->BYPASS = 0X5A5A;
  131. M0P_FLASH->BYPASS = 0XA5A5;
  132. M0P_FLASH->CR_f.WAIT = 0; // 0:Frequency<=24MHz; 1:24MHz< Frequency<=48HHz; 2:48MHz<Frequency;
  133. // 3.0) set RCH OFF
  134. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  135. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  136. M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = 0;
  137. // 3.1) RCH = 4M or 8M or 16M
  138. #if defined(SYSCLK_4M_MODE)
  139. M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C08ul))); // 4MHz
  140. #elif defined(SYSCLK_8M_MODE)
  141. M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C06ul))); // 8MHz
  142. #elif defined(SYSCLK_16M_MODE)
  143. M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C04ul))); // 16MHz
  144. #endif
  145. // 3.2) set RCH ON
  146. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  147. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  148. M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = 1;
  149. while(!M0P_SYSCTRL->RCH_CR_f.STABLE){ // wait until RCH is ready
  150. }
  151. // 4) increase Flash latency before increasing frequency(default MSI is 4MHz after reset)
  152. M0P_FLASH->BYPASS = 0X5A5A;
  153. M0P_FLASH->BYPASS = 0XA5A5;
  154. M0P_FLASH->CR_f.WAIT = 0; // 0:Frequency<=24MHz; 1:24MHz< Frequency<=48HHz; 2:48MHz<Frequency;
  155. // 5) switch to RCH
  156. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  157. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  158. M0P_SYSCTRL->SYSCTRL0_f.CLKSW = 0; // 0: RCH; 1: XTH; 2: RCL; 3: XTL; 4: PLL;
  159. #ifndef RCL_38p4K_ENABLE
  160. // 6) set RCL OFF
  161. M0P_SYSCTRL->SYSCTRL2 = 0X5A5A;
  162. M0P_SYSCTRL->SYSCTRL2 = 0XA5A5;
  163. M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = 0;
  164. #endif
  165. }
  166. void IRQMutEnable(IRQn_Type IRQn, uint32_t Priority)
  167. {
  168. rt_base_t level;
  169. level = rt_hw_interrupt_disable();
  170. NVIC_SetPriority(IRQn, Priority); // set interrupt priority
  171. NVIC_EnableIRQ(IRQn); // enable interrrupt
  172. rt_hw_interrupt_enable(level);
  173. }
  174. /* SysTick configuration */
  175. // systick is 4194.304ms(4MHz) or 2097.152ms(8MHz) interval
  176. void systick_init(void)
  177. {
  178. // IRQMutEnable(SysTick_IRQn, IRQnPriority0);
  179. // set SYSTICK period 1ms
  180. //#if defined(SYSCLK_4M_MODE)
  181. // SysTick->LOAD = 4000000 - 1;
  182. //#elif defined(SYSCLK_8M_MODE)
  183. // SysTick->LOAD = 8000000 - 1;
  184. //#elif defined(SYSCLK_16M_MODE)
  185. // SysTick->LOAD = 16000000 - 1;
  186. //#endif
  187. SysTick->LOAD = 0x00FFFFFF;
  188. SysTick->VAL = 0UL;
  189. SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk) | // systick clksource is HCLK
  190. // (SysTick_CTRL_TICKINT_Msk) | // systick interrupt enable
  191. (SysTick_CTRL_ENABLE_Msk); // systick enable
  192. }
  193. //void get_tick(uint32_t *tick, uint32_t *sub)
  194. //{
  195. // uint32_t pre_tick;
  196. //
  197. //// rt_enter_critical();
  198. // pre_tick = rt_tick_get();
  199. // *sub = SysTick->VAL;
  200. // *tick = rt_tick_get();
  201. //
  202. // if (pre_tick!=*tick){
  203. // *sub = SysTick->VAL;
  204. // }
  205. //// rt_exit_critical();
  206. //}
  207. /**
  208. * This function will delay for some us, but not release CPU.
  209. *
  210. * @param us the delay time of us, us < 4194304(4MHz) or 2097152(8MHz) or 1048576(16MHz)
  211. */
  212. //modified by yuewei 20260306 start
  213. /*
  214. void us_delay(uint32_t us)
  215. {
  216. uint32_t start, now, delta, us_tick;
  217. start = SysTick->VAL;
  218. #if defined(SYSCLK_4M_MODE)
  219. us_tick = us*4;
  220. #elif defined(SYSCLK_8M_MODE)
  221. us_tick = us*8;
  222. #elif defined(SYSCLK_16M_MODE)
  223. us_tick = us*16;
  224. #endif
  225. do {
  226. now = SysTick->VAL;
  227. delta = start > now ? start - now : 0x1000000 + start - now;
  228. } while(delta < us_tick);
  229. }
  230. */
  231. /**
  232. * @brief 基于_nop_()的微秒延时函数
  233. * @param us: 要延时的微秒数(建议范围:1~1000,过长会导致CPU空转)
  234. * @return 无
  235. */
  236. __attribute__((optnone))//add by yuewei to void not work in O1
  237. void us_delay(uint32_t us)
  238. {
  239. uint32_t i, j, CPU_FREQ_MHZ;
  240. #if defined(SYSCLK_4M_MODE)
  241. CPU_FREQ_MHZ = 4;
  242. #elif defined(SYSCLK_8M_MODE)
  243. CPU_FREQ_MHZ = 8;
  244. #elif defined(SYSCLK_16M_MODE)
  245. CPU_FREQ_MHZ = 16;
  246. #endif
  247. // 外层循环:控制总延时us数
  248. for (i = 0; i < us; i++)
  249. {
  250. // 内层循环:凑够1us的NOP次数(CPU_FREQ_MHZ = 主频(MHz))
  251. for (j = 0; j < CPU_FREQ_MHZ; j++)
  252. {
  253. __NOP(); // 执行1次空指令,占用1个CPU时钟周期
  254. }
  255. }
  256. }
  257. //modified by yuewei 20260306 end
  258. uint32_t expire_systick = 0x80000000u;
  259. // SysTick-VAL is count-down every clock
  260. // [us] < 2097152(4MHz) or 1048576(8MHz)
  261. void CalExpireTime(uint32_t us)
  262. {
  263. uint32_t new_systick;
  264. uint32_t delta;
  265. #if defined(SYSCLK_4M_MODE)
  266. us *= 4;
  267. #elif defined(SYSCLK_8M_MODE)
  268. us *= 8;
  269. #elif defined(SYSCLK_16M_MODE)
  270. us *= 16;
  271. #endif
  272. new_systick = (SysTick->VAL - us) & 0xFFFFFFu;
  273. if (expire_systick&0x80000000u){
  274. expire_systick = new_systick;
  275. } else {
  276. delta = (expire_systick - new_systick) & 0xFFFFFFu;
  277. if (delta<0x800000u){
  278. expire_systick = new_systick;
  279. }
  280. }
  281. }
  282. void WaitExpireTime(void)
  283. {
  284. uint32_t delta;
  285. if (expire_systick&0x80000000u){
  286. return;
  287. }
  288. while(1){
  289. delta = (expire_systick - SysTick->VAL) & 0xFFFFFFu;
  290. if (delta<0x800000u){
  291. expire_systick = 0x80000000u;
  292. return;
  293. }
  294. }
  295. }
  296. //uint32_t dbg_chk_runtime_start_tp;
  297. //uint32_t dbg_chk_runtime_end_tp;
  298. //uint32_t dbg_chk_runtime_diff_tp;
  299. //uint32_t dbg_chk_runtime_flag=0;
  300. //uint32_t dbg_chk_runtime_diff_max=0;
  301. //
  302. //// time range must be less than 4095 ms
  303. //void DebugChkRuntime(uint32_t mode, uint32_t op)
  304. //{
  305. // uint32_t tick, sub;
  306. // uint32_t diff_tick;
  307. //
  308. // get_tick(&tick, &sub);
  309. //
  310. // if (mode&0x1UL) {
  311. // dbg_chk_runtime_start_tp = (tick<<20) | sub;
  312. // }
  313. //
  314. // if (mode&0x2UL) {
  315. // dbg_chk_runtime_end_tp = sub | (tick<<20);
  316. // diff_tick = (dbg_chk_runtime_end_tp>>20) - (dbg_chk_runtime_start_tp>>20);
  317. // if (diff_tick>>31){
  318. // diff_tick += (0x1u<<12);
  319. // }
  320. // diff_tick *= (SysTick->LOAD + 1);
  321. // dbg_chk_runtime_diff_tp = (dbg_chk_runtime_start_tp&0xfffff) - (dbg_chk_runtime_end_tp&0xfffff) + diff_tick;
  322. // if (dbg_chk_runtime_diff_tp > op) {
  323. // dbg_chk_runtime_flag |= 0x1;
  324. // }
  325. //
  326. // if (dbg_chk_runtime_diff_tp > dbg_chk_runtime_diff_max) {
  327. // dbg_chk_runtime_diff_max = dbg_chk_runtime_diff_tp;
  328. // }
  329. //
  330. // if (mode&(0x1UL<<31)) {
  331. // rt_kprintf("***start:0x%x->end:0x%x(%d clock elapsed)***\n", dbg_chk_runtime_start_tp, dbg_chk_runtime_end_tp, dbg_chk_runtime_diff_tp);
  332. // }
  333. //
  334. // if (mode&0x4UL){
  335. // dbg_chk_runtime_start_tp = dbg_chk_runtime_end_tp;
  336. // }
  337. // }
  338. //}
  339. //void SysTick_Handler(void)
  340. //{
  341. // rt_interrupt_enter();
  342. //
  343. //// extern void ADC1_StartSingleSequence(void);
  344. //// ADC1_StartSingleSequence();
  345. //
  346. // rt_tick_increase();
  347. //
  348. // rt_interrupt_leave();
  349. //}
  350. //
  351. //void rt_system_power_manager(void)
  352. //{
  353. // __WFI();
  354. //}
  355. /**
  356. * This function will initial board.
  357. */
  358. //void rt_hw_board_init()
  359. //{
  360. // /* Heap initialization */
  361. //#if defined(RT_USING_HEAP)
  362. // rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
  363. //#endif
  364. //
  365. // lvd_init();
  366. //
  367. //#if defined(RT_USING_FINSH)
  368. // extern void finsh_drv_init(void);
  369. // finsh_drv_init();
  370. //#endif
  371. //
  372. // rt_hw_systick_init();
  373. //
  374. //#if defined(RT_USING_IDLE_HOOK) && defined(RT_USING_CPU_USAGE)
  375. // extern void cpu_usage_init(void);
  376. // cpu_usage_init();
  377. //#endif
  378. //
  379. // /* Board underlying hardware initialization */
  380. //#ifdef RT_USING_COMPONENTS_INIT
  381. // rt_components_board_init();
  382. //#endif
  383. //}