drv_systick.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-11-11 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include "rtthread.h"
  13. #include "NuMicro.h"
  14. #include "drv_sys.h"
  15. #include "nu_timer.h"
  16. #define USE_TIMER 4
  17. /* Concatenate */
  18. #define _CONCAT2_(x, y) x##y
  19. #define _CONCAT3_(x, y, z) x##y##z
  20. #define CONCAT2(x, y) _CONCAT2_(x, y)
  21. #define CONCAT3(x, y, z) _CONCAT3_(x,y,z)
  22. /* Concatenate the macros of timer instance for driver usage. */
  23. #define SYSTICK_IRQ CONCAT2(IRQ_TMR, USE_TIMER )
  24. #define SYSTICK_CLKEN CONCAT3(TIMER, USE_TIMER, CKEN)
  25. #define SYSTICK_RST CONCAT3(TIMER, USE_TIMER, RST)
  26. static void nu_systick_isr(int vector, void *param)
  27. {
  28. rt_tick_increase();
  29. TIMER_ClearIntFlag(USE_TIMER);
  30. }
  31. void rt_hw_systick_init(void)
  32. {
  33. nu_sys_ipclk_enable(SYSTICK_CLKEN);
  34. nu_sys_ip_reset(SYSTICK_RST);
  35. // Set timer frequency
  36. TIMER_Open(USE_TIMER, TIMER_PERIODIC_MODE, RT_TICK_PER_SECOND);
  37. // Enable timer interrupt
  38. TIMER_EnableInt(USE_TIMER);
  39. rt_hw_interrupt_install(SYSTICK_IRQ, nu_systick_isr, RT_NULL, "systick");
  40. rt_hw_interrupt_set_priority(SYSTICK_IRQ, IRQ_LEVEL_1);
  41. rt_hw_interrupt_umask(SYSTICK_IRQ);
  42. TIMER_Start(USE_TIMER);
  43. } /* rt_hw_systick_init */
  44. void rt_hw_us_delay(rt_uint32_t us)
  45. {
  46. rt_uint32_t ticks;
  47. rt_uint32_t told, tnow, tcnt = 0;
  48. rt_uint32_t cmp = TIMER_GetCompareData(USE_TIMER);
  49. ticks = us * cmp / (1000000 / RT_TICK_PER_SECOND);
  50. told = TIMER_GetCounter(USE_TIMER);
  51. while (1)
  52. {
  53. /* Timer counter is increment. */
  54. tnow = TIMER_GetCounter(USE_TIMER);
  55. if (tnow != told)
  56. {
  57. /* 0 -- old === now -------- cmp */
  58. if (tnow > told)
  59. {
  60. tcnt += tnow - told;
  61. }
  62. else
  63. {
  64. /* 0 == now --- old ======== cmp */
  65. tcnt += cmp - told + tnow;
  66. }
  67. told = tnow;
  68. /* Timeout */
  69. if (tcnt >= ticks)
  70. {
  71. break;
  72. }
  73. }
  74. }
  75. } /* rt_hw_us_delay */