irsony.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (C) 2003 by egnite Software GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /*!
  34. * \file arch/avr/dev/irsony.c
  35. * \brief AVR support for Sony IR protocol.
  36. *
  37. * \verbatim
  38. * $Id: irsony.c 4706 2012-10-06 17:42:01Z haraldkipp $
  39. * \endverbatim
  40. */
  41. #include <cfg/medianut.h>
  42. #include <sys/atom.h>
  43. #include <sys/event.h>
  44. #ifdef __IMAGECRAFT__
  45. #pragma interrupt_handler INT4_vect:iv_INT4
  46. #pragma interrupt_handler TIMER2_OVF_vect:iv_TIMER2_OVF
  47. #endif
  48. /*!
  49. * \addtogroup xgIrSony
  50. */
  51. /*@{*/
  52. #include <dev/irsony.h>
  53. #define IRTIMER_START 0xF0
  54. #define IRTIMER_SCALE 0x01
  55. /*!
  56. * \brief Last valid infrared code received.
  57. */
  58. long nut_ircode;
  59. /*!
  60. * \brief Queue of threads waiting for infrared input.
  61. */
  62. HANDLE nut_irqueue;
  63. /*
  64. * Tick counter, incremented on each timer overflow and
  65. * cleared on each edge detection on the infrared signal.
  66. */
  67. static uint16_t irticks;
  68. /*
  69. * Number of bits received from infrared decoder.
  70. */
  71. static uint8_t irbitnum;
  72. /*! \fn TIMER2_OVF_vect(void)
  73. * \brief Timer 2 overflow handler.
  74. */
  75. SIGNAL(TIMER2_OVF_vect)
  76. {
  77. /* Set the timer value. */
  78. outb(TCNT2, IRTIMER_START);
  79. /*
  80. * Increment our tick counter. If it overflows, then wait
  81. * for the next start bit and disable the timer.
  82. */
  83. if (++irticks == 0) {
  84. irbitnum = 0;
  85. cbi(TIMSK, 6);
  86. }
  87. }
  88. /*! \fn INT4_vect(void)
  89. * \brief Infrared decoder signal edge handler.
  90. */
  91. SIGNAL(INT4_vect)
  92. {
  93. static uint16_t minset; /* Min. length of bit value 1, calculated from start bit. */
  94. static uint16_t ccode; /* Current code. */
  95. static uint16_t lcode; /* Last code. */
  96. static uint8_t ncode; /* Number of equal codes. */
  97. uint16_t bitlen = irticks; /* Length of the current bit. */
  98. irticks = 0;
  99. /* Rising egde marks end of bit. */
  100. if (inb(IR_SIGNAL_PIN) & _BV(IR_SIGNAL_BIT)) {
  101. /* Start bit. */
  102. if (irbitnum++ == 0) {
  103. ccode = 0;
  104. minset = bitlen / 3;
  105. }
  106. /* Data bits. */
  107. else {
  108. /* If its length is greater than a third of the start bit,
  109. then we assume this bit set. */
  110. if (bitlen >= minset)
  111. ccode |= _BV(12);
  112. ccode >>= 1;
  113. /* All data bits collected? */
  114. if (irbitnum > 12) {
  115. cbi(TIMSK, 6);
  116. irbitnum = 0;
  117. if (ncode++) {
  118. if (lcode != ccode)
  119. ncode = 0;
  120. /* If we have two equal codes, pass it to the
  121. application. */
  122. else if (ncode > 1) {
  123. ncode = 0;
  124. nut_ircode = ccode;
  125. NutEventPostFromIrq(&nut_irqueue);
  126. }
  127. } else
  128. lcode = ccode;
  129. }
  130. }
  131. }
  132. /* Falling edges mark the start of a bit. Enable timer
  133. overflow interrupts. */
  134. else if (irbitnum == 0) {
  135. sbi(TIMSK, 6);
  136. }
  137. }
  138. /*!
  139. * \brief Enable Sony infrared remote control.
  140. */
  141. int NutIrInitSony(void)
  142. {
  143. NutEnterCritical();
  144. /*
  145. * Initialize timer 2 and enable overflow interrupts.
  146. */
  147. outb(TCNT2, IRTIMER_START);
  148. outb(TCCR2, IRTIMER_SCALE);
  149. sbi(TIMSK, 6);
  150. /*
  151. * Enable infrared decoder interrupts on both edges.
  152. */
  153. cbi(IR_SIGNAL_DDR, IR_SIGNAL_BIT);
  154. sbi(EICR, 0);
  155. cbi(EICR, 1);
  156. sbi(EIMSK, IR_SIGNAL_BIT);
  157. NutExitCritical();
  158. return 0;
  159. }
  160. /*@}*/