Alternative library and kernel for add-in development on fx-9860G and fx-CG50 under Linux.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines

  1. //---
  2. // gint:timer - Timer operation
  3. //---
  4. #ifndef GINT_TIMER
  5. #define GINT_TIMER
  6. #include <gint/defs/types.h>
  7. #include <gint/mpu/tmu.h>
  8. #include <gint/hardware.h>
  9. /* Timer identifiers
  10. Hardware timers are numbered with integers starting from 0. You can freely
  11. access all the available timers by using their number once you have
  12. configured them with timer_setup(). The number of timers depends on the MPU:
  13. SH3-based: 4 timers, ids 0..3 [SH7355, SH7337]
  14. SH4-based: 9 timers, ids 0..8 [SH7305]
  15. You should be aware that some of these timers are used by default by gint:
  16. - Timer 1 is used by the gray engine on fx9860g.
  17. - Timer 3 is used by the keyboard, unless GINT_RTC_KEYBOARD is defined. This
  18. macro is controlled by the -rtc-keyboard switch when gint is compiled.
  19. timer_setup() will fail if you try to use a timer that's already running.
  20. Always check the return value of timer_setup()! Using a timer id that has
  21. not been validated by timer_setup() will work, but do *something else* than
  22. what you intended. */
  23. /* timer_count() - tells how many timers are available on the platform */
  24. #define timer_count() (isSH3() ? 4 : 9)
  25. /* Clock input
  26. Timers count down when their input clock ticks, and fire when their counter
  27. reach 0. The choice of the input clock influences the resolution of the
  28. timer, but if the clock is too fast, the 32-bit counter might not be able to
  29. represent long delays.
  30. Several input clocks are available. The peripheral clock (Po) can be divided
  31. by 4, 16, 64 or 256; as an alternative the external clock TCLK can be used
  32. for counting. I suspect TCLK runs at a fixed frequency of 32768 Hz, but this
  33. has yet to be verified.
  34. You don't really need to choose an input clock unless you are doing
  35. something very specific. In most practical cases you can use timer_default
  36. which is 0. See the timer_delay() function for more information. */
  37. typedef enum
  38. {
  39. timer_Po_4 = 0,
  40. timer_Po_16 = 1,
  41. timer_Po_64 = 2,
  42. timer_Po_256 = 3,
  43. timer_TCLK = 5,
  44. timer_default = timer_Po_4,
  45. } timer_input_t;
  46. //---
  47. // Timer functions
  48. //---
  49. /* timer_setup() - set up a timer
  50. This function configures the requested timer without starting it. On
  51. success, it returns the first argument "timer", which is used as a timer
  52. identifier in all other timer functions. If the requested timer is already
  53. in use, this function fails and returns a negative number.
  54. This function sets the timer delay, the clock source, and registers a
  55. callback function to be called when the timer fires. An argument can be
  56. supplied to the callback function in the form of a pointer.
  57. When the timer fires, the callback function is called with the provided
  58. argument pointer. The callback decides whether the timer should continue
  59. running (by returning 0) or stop (by returning nonzero). In the latter case,
  60. events accumulated while the callback was running are dropped.
  61. It is sometimes difficult to choose a timer constant and a clock source
  62. given a wished delay in seconds, especially when overclock is used. The
  63. timer_delay() function is provided for this purpose.
  64. @timer Requested timer id
  65. @delay Delay between each event (the unit depends on the clock source)
  66. @clock Clock source used by the timer for counting down
  67. @callback Callback function (called when the timer fires)
  68. @arg Passed as argument to the callback function */
  69. int timer_setup(int timer, uint32_t delay, timer_input_t clock,
  70. int (*callback)(volatile void *arg), volatile void *arg);
  71. /* timer_delay() - compute a delay constant from a duration in seconds
  72. This function can used as a facility to calculate the [delay] argument to
  73. the timer_setup() function. It takes a microsecond delay as an argument and
  74. returns the corresponding timer constant. A typical use to start a timer
  75. with a 25 ms interval would be:
  76. timer_setup(0, timer_delay(0, 25 * 1000), 0, callback, arg);
  77. WARNING: Only timers 0 to 2 can count microseconds! Other timers have a
  78. resolution of around 30 us. Counting in ms is safe for all timers, though.
  79. For standard timers (0 to 2) it uses Po / 4 as clock input, which is very
  80. precise and can represent up to 3 minutes' time; for extra timers (3 and
  81. above) the clock is fixed to 32768 Hz.
  82. @timer The timer you are planning to use
  83. @delay_us Requested delay in microseconds */
  84. uint32_t timer_delay(int timer, uint64_t delay_us);
  85. /* timer_start() - start a configured timer
  86. The specified timer will start counting down and fire callbacks at regular
  87. intervals.
  88. @timer Timer id, as returned by timer_setup() */
  89. void timer_start(int timer);
  90. /* timer_reload() - change a timer's delay constant for next interrupts
  91. Changes the delay constant of the given timer. Nothing will happen until the
  92. next callback; then the timer will update its delay to reflect the new
  93. constant. The new delay can be calculated by the timer_delay() function.
  94. @timer Timer id, as returned by timer_setup()
  95. @delay New delay (unit depends on the clock source) */
  96. void timer_reload(int timer, uint32_t delay);
  97. /* timer_pause() - stop a running timer
  98. The specified timer will be paused; its counter will not be reset. A stopped
  99. timer can be resumed anytime by calling timer_start(). If you want to also
  100. reset the counter, use timer_reload().
  101. @timer Timer id, as returned by timer_setup() */
  102. void timer_pause(int timer);
  103. /* timer_stop() - stop and free a timer
  104. Stops and destroys a timer, making its id free for re-use. The id must not
  105. be used anymore until it is returned by a further call to timer_setup().
  106. @timer Timer id, as returned by timer_setup() */
  107. void timer_stop(int timer);
  108. //---
  109. // Predefined timer callbacks
  110. //---
  111. /* timer_timeout() - callback that sets a flag and halts the timer
  112. This predefined callback may be used when a timeout is required. It sets its
  113. argument pointer to 1 and halts the timer. The pointer must be of type
  114. int * and you must declare the variable as volatile int. */
  115. int timer_timeout(volatile void *arg);
  116. //---
  117. // Low-level functions
  118. //---
  119. /* timer_address() - get the address of a timer structure
  120. Returns a tmu_t if the id is 0, 1 or 2 and an etmu_t otherwise. The address
  121. will be NULL if the requested timer does not exist.
  122. @timer Requested timer
  123. @TSTR If the requested timer is a TMU, set to the TSTR address */
  124. void *timer_address(int timer, volatile uint8_t **TSTR);
  125. #endif /* GINT_TIMER */