hw_timer.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /******************************************************************************
  2. * Copyright 2013-2014 Espressif Systems (Wuxi)
  3. *
  4. * FileName: hw_timer.c
  5. *
  6. * Description: hw_timer driver
  7. *
  8. * Modification history:
  9. * 2014/5/1, v1.0 create this file.
  10. *
  11. * Adapted for NodeMCU 2016
  12. *
  13. * The owner parameter should be a unique value per module using this API
  14. * It could be a pointer to a bit of data or code
  15. * e.g. #define OWNER ((os_param_t) module_init)
  16. * where module_init is a function. For builtin modules, it might be
  17. * a small numeric value that is known not to clash.
  18. *******************************************************************************/
  19. #include "ets_sys.h"
  20. #include "os_type.h"
  21. #include "osapi.h"
  22. #include "hw_timer.h"
  23. #define FRC1_ENABLE_TIMER BIT7
  24. #define FRC1_AUTO_LOAD BIT6
  25. //TIMER PREDIVIDED MODE
  26. typedef enum {
  27. DIVIDED_BY_1 = 0, //timer clock
  28. DIVIDED_BY_16 = 4, //divided by 16
  29. DIVIDED_BY_256 = 8, //divided by 256
  30. } TIMER_PREDIVIDED_MODE;
  31. typedef enum { //timer interrupt mode
  32. TM_LEVEL_INT = 1, // level interrupt
  33. TM_EDGE_INT = 0, //edge interrupt
  34. } TIMER_INT_MODE;
  35. static os_param_t the_owner;
  36. static os_param_t callback_arg;
  37. static void (* user_hw_timer_cb)(os_param_t);
  38. #define VERIFY_OWNER(owner) if (owner != the_owner) { if (the_owner) { return 0; } the_owner = owner; }
  39. /******************************************************************************
  40. * FunctionName : platform_hw_timer_arm_ticks
  41. * Description : set a trigger timer delay for this timer.
  42. * Parameters : os_param_t owner
  43. * uint32 ticks :
  44. * Returns : true if it worked
  45. *******************************************************************************/
  46. bool ICACHE_RAM_ATTR platform_hw_timer_arm_ticks(os_param_t owner, uint32_t ticks)
  47. {
  48. VERIFY_OWNER(owner);
  49. RTC_REG_WRITE(FRC1_LOAD_ADDRESS, ticks);
  50. return 1;
  51. }
  52. /******************************************************************************
  53. * FunctionName : platform_hw_timer_arm_us
  54. * Description : set a trigger timer delay for this timer.
  55. * Parameters : os_param_t owner
  56. * uint32 microseconds :
  57. * in autoload mode
  58. * 50 ~ 0x7fffff; for FRC1 source.
  59. * 100 ~ 0x7fffff; for NMI source.
  60. * in non autoload mode:
  61. * 10 ~ 0x7fffff;
  62. * Returns : true if it worked
  63. *******************************************************************************/
  64. bool ICACHE_RAM_ATTR platform_hw_timer_arm_us(os_param_t owner, uint32_t microseconds)
  65. {
  66. VERIFY_OWNER(owner);
  67. RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(microseconds));
  68. return 1;
  69. }
  70. /******************************************************************************
  71. * FunctionName : platform_hw_timer_set_func
  72. * Description : set the func, when trigger timer is up.
  73. * Parameters : os_param_t owner
  74. * void (* user_hw_timer_cb_set)(os_param_t):
  75. timer callback function
  76. * os_param_t arg
  77. * Returns : true if it worked
  78. *******************************************************************************/
  79. bool platform_hw_timer_set_func(os_param_t owner, void (* user_hw_timer_cb_set)(os_param_t), os_param_t arg)
  80. {
  81. VERIFY_OWNER(owner);
  82. callback_arg = arg;
  83. user_hw_timer_cb = user_hw_timer_cb_set;
  84. return 1;
  85. }
  86. static void ICACHE_RAM_ATTR hw_timer_isr_cb(void *arg)
  87. {
  88. if (user_hw_timer_cb != NULL) {
  89. (*(user_hw_timer_cb))(callback_arg);
  90. }
  91. }
  92. static void ICACHE_RAM_ATTR hw_timer_nmi_cb(void)
  93. {
  94. if (user_hw_timer_cb != NULL) {
  95. (*(user_hw_timer_cb))(callback_arg);
  96. }
  97. }
  98. /******************************************************************************
  99. * FunctionName : platform_hw_timer_get_delay_ticks
  100. * Description : figure out how long since th last timer interrupt
  101. * Parameters : os_param_t owner
  102. * Returns : the number of ticks
  103. *******************************************************************************/
  104. uint32_t ICACHE_RAM_ATTR platform_hw_timer_get_delay_ticks(os_param_t owner)
  105. {
  106. VERIFY_OWNER(owner);
  107. return (- RTC_REG_READ(FRC1_COUNT_ADDRESS)) & ((1 << 23) - 1);
  108. }
  109. /******************************************************************************
  110. * FunctionName : platform_hw_timer_init
  111. * Description : initialize the hardware isr timer
  112. * Parameters : os_param_t owner
  113. * FRC1_TIMER_SOURCE_TYPE source_type:
  114. * FRC1_SOURCE, timer use frc1 isr as isr source.
  115. * NMI_SOURCE, timer use nmi isr as isr source.
  116. * bool autoload:
  117. * 0, not autoload,
  118. * 1, autoload mode,
  119. * Returns : true if it worked
  120. *******************************************************************************/
  121. bool platform_hw_timer_init(os_param_t owner, FRC1_TIMER_SOURCE_TYPE source_type, bool autoload)
  122. {
  123. VERIFY_OWNER(owner);
  124. if (autoload) {
  125. RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
  126. FRC1_AUTO_LOAD | DIVIDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
  127. } else {
  128. RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
  129. DIVIDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
  130. }
  131. if (source_type == NMI_SOURCE) {
  132. ETS_FRC_TIMER1_NMI_INTR_ATTACH(hw_timer_nmi_cb);
  133. } else {
  134. ETS_FRC_TIMER1_INTR_ATTACH(hw_timer_isr_cb, NULL);
  135. }
  136. TM1_EDGE_INT_ENABLE();
  137. ETS_FRC1_INTR_ENABLE();
  138. return 1;
  139. }
  140. /******************************************************************************
  141. * FunctionName : platform_hw_timer_close
  142. * Description : ends use of the hardware isr timer
  143. * Parameters : os_param_t owner
  144. * Returns : true if it worked
  145. *******************************************************************************/
  146. bool ICACHE_RAM_ATTR platform_hw_timer_close(os_param_t owner)
  147. {
  148. VERIFY_OWNER(owner);
  149. /* Set no reload mode */
  150. RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
  151. DIVIDED_BY_16 | TM_EDGE_INT);
  152. TM1_EDGE_INT_DISABLE();
  153. ETS_FRC1_INTR_DISABLE();
  154. user_hw_timer_cb = NULL;
  155. the_owner = 0;
  156. return 1;
  157. }