hw_timer.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. #include "ets_sys.h"
  12. #include "os_type.h"
  13. #include "osapi.h"
  14. #define US_TO_RTC_TIMER_TICKS(t) \
  15. ((t) ? \
  16. (((t) > 0x35A) ? \
  17. (((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000)) : \
  18. (((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \
  19. 0)
  20. #define FRC1_ENABLE_TIMER BIT7
  21. #define FRC1_AUTO_LOAD BIT6
  22. //TIMER PREDIVED MODE
  23. typedef enum {
  24. DIVDED_BY_1 = 0, //timer clock
  25. DIVDED_BY_16 = 4, //divided by 16
  26. DIVDED_BY_256 = 8, //divided by 256
  27. } TIMER_PREDIVED_MODE;
  28. typedef enum { //timer interrupt mode
  29. TM_LEVEL_INT = 1, // level interrupt
  30. TM_EDGE_INT = 0, //edge interrupt
  31. } TIMER_INT_MODE;
  32. typedef enum {
  33. FRC1_SOURCE = 0,
  34. NMI_SOURCE = 1,
  35. } FRC1_TIMER_SOURCE_TYPE;
  36. /******************************************************************************
  37. * FunctionName : hw_timer_arm
  38. * Description : set a trigger timer delay for this timer.
  39. * Parameters : uint32 val :
  40. in autoload mode
  41. 50 ~ 0x7fffff; for FRC1 source.
  42. 100 ~ 0x7fffff; for NMI source.
  43. in non autoload mode:
  44. 10 ~ 0x7fffff;
  45. * Returns : NONE
  46. *******************************************************************************/
  47. void hw_timer_arm(u32 val)
  48. {
  49. RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val));
  50. }
  51. static void (* user_hw_timer_cb)(void) = NULL;
  52. /******************************************************************************
  53. * FunctionName : hw_timer_set_func
  54. * Description : set the func, when trigger timer is up.
  55. * Parameters : void (* user_hw_timer_cb_set)(void):
  56. timer callback function,
  57. * Returns : NONE
  58. *******************************************************************************/
  59. void hw_timer_set_func(void (* user_hw_timer_cb_set)(void))
  60. {
  61. user_hw_timer_cb = user_hw_timer_cb_set;
  62. }
  63. static void hw_timer_isr_cb(void)
  64. {
  65. if (user_hw_timer_cb != NULL) {
  66. (*(user_hw_timer_cb))();
  67. }
  68. }
  69. /******************************************************************************
  70. * FunctionName : hw_timer_init
  71. * Description : initilize the hardware isr timer
  72. * Parameters :
  73. FRC1_TIMER_SOURCE_TYPE source_type:
  74. FRC1_SOURCE, timer use frc1 isr as isr source.
  75. NMI_SOURCE, timer use nmi isr as isr source.
  76. u8 req:
  77. 0, not autoload,
  78. 1, autoload mode,
  79. * Returns : NONE
  80. *******************************************************************************/
  81. void ICACHE_FLASH_ATTR hw_timer_init(FRC1_TIMER_SOURCE_TYPE source_type, u8 req)
  82. {
  83. if (req == 1) {
  84. RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
  85. FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
  86. } else {
  87. RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
  88. DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
  89. }
  90. if (source_type == NMI_SOURCE) {
  91. ETS_FRC_TIMER1_NMI_INTR_ATTACH(hw_timer_isr_cb);
  92. } else {
  93. ETS_FRC_TIMER1_INTR_ATTACH(hw_timer_isr_cb, NULL);
  94. }
  95. TM1_EDGE_INT_ENABLE();
  96. ETS_FRC1_INTR_ENABLE();
  97. }
  98. //-------------------------------Test Code Below--------------------------------------
  99. #if 0
  100. void hw_test_timer_cb(void)
  101. {
  102. static uint16 j = 0;
  103. j++;
  104. if ((WDEV_NOW() - tick_now2) >= 1000000) {
  105. static u32 idx = 1;
  106. tick_now2 = WDEV_NOW();
  107. os_printf("b%u:%d\n", idx++, j);
  108. j = 0;
  109. }
  110. //hw_timer_arm(50);
  111. }
  112. void ICACHE_FLASH_ATTR user_init(void)
  113. {
  114. hw_timer_init(FRC1_SOURCE, 1);
  115. hw_timer_set_func(hw_test_timer_cb);
  116. hw_timer_arm(100);
  117. }
  118. #endif
  119. /*
  120. NOTE:
  121. 1 if use nmi source, for autoload timer , the timer setting val can't be less than 100.
  122. 2 if use nmi source, this timer has highest priority, can interrupt other isr.
  123. 3 if use frc1 source, this timer can't interrupt other isr.
  124. */