hw_timer.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * ESPRSSIF MIT License
  3. *
  4. * Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
  5. *
  6. * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
  7. * it is free of charge, to any person obtaining a copy of this software and associated
  8. * documentation files (the "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
  11. * to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all copies or
  14. * substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. */
  24. #include "ets_sys.h"
  25. #include "os_type.h"
  26. #include "osapi.h"
  27. #define US_TO_RTC_TIMER_TICKS(t) \
  28. ((t) ? \
  29. (((t) > 0x35A) ? \
  30. (((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000)) : \
  31. (((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \
  32. 0)
  33. #define FRC1_ENABLE_TIMER BIT7
  34. #define FRC1_AUTO_LOAD BIT6
  35. //TIMER PREDIVED MODE
  36. typedef enum {
  37. DIVDED_BY_1 = 0, //timer clock
  38. DIVDED_BY_16 = 4, //divided by 16
  39. DIVDED_BY_256 = 8, //divided by 256
  40. } TIMER_PREDIVED_MODE;
  41. typedef enum { //timer interrupt mode
  42. TM_LEVEL_INT = 1, // level interrupt
  43. TM_EDGE_INT = 0, //edge interrupt
  44. } TIMER_INT_MODE;
  45. typedef enum {
  46. FRC1_SOURCE = 0,
  47. NMI_SOURCE = 1,
  48. } FRC1_TIMER_SOURCE_TYPE;
  49. /******************************************************************************
  50. * FunctionName : hw_timer_arm
  51. * Description : set a trigger timer delay for this timer.
  52. * Parameters : uint32 val :
  53. in autoload mode
  54. 50 ~ 0x7fffff; for FRC1 source.
  55. 100 ~ 0x7fffff; for NMI source.
  56. in non autoload mode:
  57. 10 ~ 0x7fffff;
  58. * Returns : NONE
  59. *******************************************************************************/
  60. void hw_timer_arm(u32 val)
  61. {
  62. RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val));
  63. }
  64. static void (* user_hw_timer_cb)(void) = NULL;
  65. /******************************************************************************
  66. * FunctionName : hw_timer_set_func
  67. * Description : set the func, when trigger timer is up.
  68. * Parameters : void (* user_hw_timer_cb_set)(void):
  69. timer callback function,
  70. * Returns : NONE
  71. *******************************************************************************/
  72. void hw_timer_set_func(void (* user_hw_timer_cb_set)(void))
  73. {
  74. user_hw_timer_cb = user_hw_timer_cb_set;
  75. }
  76. static void hw_timer_isr_cb(void)
  77. {
  78. if (user_hw_timer_cb != NULL) {
  79. (*(user_hw_timer_cb))();
  80. }
  81. }
  82. /******************************************************************************
  83. * FunctionName : hw_timer_init
  84. * Description : initilize the hardware isr timer
  85. * Parameters :
  86. FRC1_TIMER_SOURCE_TYPE source_type:
  87. FRC1_SOURCE, timer use frc1 isr as isr source.
  88. NMI_SOURCE, timer use nmi isr as isr source.
  89. u8 req:
  90. 0, not autoload,
  91. 1, autoload mode,
  92. * Returns : NONE
  93. *******************************************************************************/
  94. void ICACHE_FLASH_ATTR hw_timer_init(FRC1_TIMER_SOURCE_TYPE source_type, u8 req)
  95. {
  96. if (req == 1) {
  97. RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
  98. FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
  99. } else {
  100. RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
  101. DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
  102. }
  103. if (source_type == NMI_SOURCE) {
  104. ETS_FRC_TIMER1_NMI_INTR_ATTACH(hw_timer_isr_cb);
  105. } else {
  106. ETS_FRC_TIMER1_INTR_ATTACH(hw_timer_isr_cb, NULL);
  107. }
  108. TM1_EDGE_INT_ENABLE();
  109. ETS_FRC1_INTR_ENABLE();
  110. }
  111. //-------------------------------Test Code Below--------------------------------------
  112. #if 0
  113. void hw_test_timer_cb(void)
  114. {
  115. static uint16 j = 0;
  116. j++;
  117. if ((WDEV_NOW() - tick_now2) >= 1000000) {
  118. static u32 idx = 1;
  119. tick_now2 = WDEV_NOW();
  120. os_printf("b%u:%d\n", idx++, j);
  121. j = 0;
  122. }
  123. //hw_timer_arm(50);
  124. }
  125. void ICACHE_FLASH_ATTR user_init(void)
  126. {
  127. hw_timer_init(FRC1_SOURCE, 1);
  128. hw_timer_set_func(hw_test_timer_cb);
  129. hw_timer_arm(100);
  130. }
  131. #endif
  132. /*
  133. NOTE:
  134. 1 if use nmi source, for autoload timer , the timer setting val can't be less than 100.
  135. 2 if use nmi source, this timer has highest priority, can interrupt other isr.
  136. 3 if use frc1 source, this timer can't interrupt other isr.
  137. */