timer.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* sd2snes - SD card based universal cartridge for the SNES
  2. Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
  3. This file was adapted from sd2iec, written by Ingo Korb.
  4. Original copyright header follows:
  5. */
  6. /* sd2iec - SD/MMC to Commodore serial bus interface/controller
  7. Copyright (C) 2007-2009 Ingo Korb <ingo@akana.de>
  8. Inspiration and low-level SD/MMC access based on code from MMC2IEC
  9. by Lars Pontoppidan et al., see sdcard.c|h and config.h.
  10. FAT filesystem access based on code from ChaN and Jim Brain, see ff.c|h.
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; version 2 of the License only.
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with this program; if not, write to the Free Software
  20. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. timer.c: System timer (and button debouncer)
  22. */
  23. #include "config.h"
  24. #include <avr/interrupt.h>
  25. #include <avr/io.h>
  26. #include "avrcompat.h"
  27. #include "led.h"
  28. #include "timer.h"
  29. volatile tick_t ticks;
  30. // Logical buttons
  31. volatile uint8_t active_keys;
  32. // Physical buttons
  33. uint8_t buttonstate;
  34. tick_t lastbuttonchange;
  35. /* Called by the timer interrupt when the button state has changed */
  36. static void buttons_changed(void) {
  37. /* Check if the previous state was stable for two ticks */
  38. if (time_after(ticks, lastbuttonchange+2)) {
  39. if (active_keys & IGNORE_KEYS) {
  40. active_keys &= ~IGNORE_KEYS;
  41. } else if (!(buttonstate & (BUTTON_PREV|BUTTON_NEXT))) {
  42. /* Both buttons held down */
  43. active_keys |= KEY_HOME;
  44. } else if (!(buttonstate & BUTTON_NEXT) &&
  45. (BUTTON_PIN & BUTTON_NEXT)) {
  46. /* "Next" button released */
  47. active_keys |= KEY_NEXT;
  48. } else if (!(buttonstate & BUTTON_PREV) &&
  49. (BUTTON_PIN & BUTTON_NEXT)) {
  50. active_keys |= KEY_PREV;
  51. }
  52. }
  53. lastbuttonchange = ticks;
  54. buttonstate = BUTTON_PIN & BUTTON_MASK;
  55. }
  56. /* The main timer interrupt */
  57. ISR(TIMER1_COMPA_vect) {
  58. uint8_t tmp = BUTTON_PIN & BUTTON_MASK;
  59. if (tmp != buttonstate) {
  60. buttons_changed();
  61. }
  62. ticks++;
  63. #ifdef SINGLE_LED
  64. if (led_state & LED_ERROR) {
  65. if ((ticks & 15) == 0)
  66. DIRTY_LED_PORT ^= DIRTY_LED_BIT();
  67. } else {
  68. if ((led_state & LED_BUSY) || (led_state & LED_DIRTY)) {
  69. DIRTY_LED_ON();
  70. } else {
  71. DIRTY_LED_OFF();
  72. }
  73. }
  74. #else
  75. if (led_state & LED_ERROR)
  76. if ((ticks & 15) == 0)
  77. DIRTY_LED_PORT ^= DIRTY_LED_BIT();
  78. #endif
  79. /* Sleep button triggers when held down for 2sec */
  80. if (time_after(ticks, lastbuttonchange+2)) {
  81. if (!(buttonstate & BUTTON_NEXT) &&
  82. (buttonstate & BUTTON_PREV) &&
  83. time_after(ticks, lastbuttonchange+2*HZ) &&
  84. !key_pressed(KEY_SLEEP)) {
  85. /* Set ignore flag so the release doesn't trigger KEY_NEXT */
  86. active_keys |= KEY_SLEEP | IGNORE_KEYS;
  87. /* Avoid triggering for the next two seconds */
  88. lastbuttonchange = ticks;
  89. }
  90. }
  91. #if CONFIG_RTC_VARIANT == 1
  92. increment_rtc();
  93. #endif
  94. #ifdef CONFIG_REMOTE_DISPLAY
  95. /* Check if the display wants to be queried */
  96. if (!(SOFTI2C_PIN & _BV(SOFTI2C_BIT_INTRQ))) {
  97. active_keys |= KEY_DISPLAY;
  98. }
  99. #endif
  100. }
  101. void timer_init(void) {
  102. /* Count F_CPU/8 in timer 0 */
  103. TCCR0B = _BV(CS01);
  104. /* Set up a 100Hz interrupt using timer 1 */
  105. OCR1A = 1249;
  106. TCNT1 = 0;
  107. TCCR1A = 0;
  108. TCCR1B = _BV(WGM12) | _BV(CS10) | _BV(CS11);
  109. TIMSK1 |= _BV(OCIE1A);
  110. /* Buttons */
  111. BUTTON_DDR &= (uint8_t)~BUTTON_MASK;
  112. BUTTON_PORT |= BUTTON_MASK;
  113. }