timer.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * =====================================================================================
  3. *
  4. * ________ .__ __ ________ ____ ________
  5. * \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
  6. * / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
  7. * / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
  8. * \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
  9. * \__> \/ \/ \/ \/ \/
  10. *
  11. * www.optixx.org
  12. *
  13. *
  14. * Version: 1.0
  15. * Created: 07/21/2009 03:32:16 PM
  16. * Author: david@optixx.org
  17. *
  18. * =====================================================================================
  19. */
  20. #include <stdint.h>
  21. #include <stdio.h>
  22. #include <avr/io.h>
  23. #include <avr/interrupt.h> /* for sei() */
  24. #include "debug.h"
  25. #include "info.h"
  26. #include "sram.h"
  27. extern uint8_t snes_reset_line;
  28. #ifndef OCR1A
  29. #define OCR1A OCR1 // 2313 support
  30. #endif
  31. #ifndef WGM12
  32. #define WGM12 CTC1 // 2313 support
  33. #endif
  34. // #define XTAL 11059201L // nominal value
  35. #define XTAL 20000000UL
  36. #define DEBOUNCE 500L // debounce clock (256Hz = 4msec)
  37. #define uint8_t unsigned char
  38. #define uint unsigned int
  39. uint16_t prescaler;
  40. uint16_t volatile second; // count seconds
  41. ISR(TIMER1_COMPA_vect)
  42. {
  43. #if XTAL % DEBOUNCE // bei rest
  44. OCR1A = 20000000UL / DEBOUNCE - 1; // compare DEBOUNCE - 1 times
  45. #endif
  46. if (--prescaler == 0) {
  47. prescaler = (uint16_t) DEBOUNCE;
  48. second++; // exact one second over
  49. #if XTAL % DEBOUNCE // handle remainder
  50. OCR1A = XTAL / DEBOUNCE + XTAL % DEBOUNCE - 1; // compare once per second
  51. #endif
  52. }
  53. }
  54. void timer_start(void)
  55. {
  56. TCCR1B = (1 << WGM12) | (1 << CS10); // divide by 1
  57. // clear on compare
  58. OCR1A = XTAL / DEBOUNCE - 1UL; // Output Compare Register
  59. TCNT1 = 0; // Timmer startet mit 0
  60. second = 0;
  61. prescaler = (uint16_t) DEBOUNCE; // software teiler
  62. TIMSK1 = 1 << OCIE1A; // beim Vergleichswertes Compare Match
  63. // Interrupt (SIG_OUTPUT_COMPARE1A)
  64. sei();
  65. }
  66. uint16_t timer_stop_int(void)
  67. {
  68. uint16_t t = ((DEBOUNCE - prescaler) / DEBOUNCE) + second;
  69. return t;
  70. }