00001 /* 00002 * Copyright (C) 2003 by egnite Software GmbH. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions 00006 * are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holders nor the names of 00014 * contributors may be used to endorse or promote products derived 00015 * from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS 00018 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00019 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00020 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE 00021 * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00022 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00023 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00024 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00025 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00026 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00027 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * For additional information see http://www.ethernut.de/ 00031 * 00032 */ 00033 00034 /* 00035 * $Log: irsony.c,v $ 00036 * Revision 1.1 2005/07/26 18:02:27 haraldkipp 00037 * Moved from dev. 00038 * 00039 * Revision 1.3 2005/01/28 12:13:14 freckle 00040 * changed NutEventPostFromIRQ into NutEventPostFromIrq 00041 * 00042 * Revision 1.2 2004/03/18 18:41:18 haraldkipp 00043 * Bugfix. Now works with ICCAVR 00044 * 00045 * Revision 1.1 2003/07/21 18:07:54 haraldkipp 00046 * Sony infrared remote control driver added 00047 * 00048 */ 00049 00050 #include <cfg/medianut.h> 00051 #include <sys/atom.h> 00052 #include <sys/event.h> 00053 00054 #ifdef __IMAGECRAFT__ 00055 #pragma interrupt_handler SIG_INTERRUPT4:iv_INT4 00056 #pragma interrupt_handler SIG_OVERFLOW2:iv_TIMER2_OVF 00057 #endif 00058 00063 00064 #include <dev/irsony.h> 00065 00066 #define IRTIMER_START 0xF0 00067 #define IRTIMER_SCALE 0x01 00068 00072 long nut_ircode; 00073 00077 HANDLE nut_irqueue; 00078 00079 /* 00080 * Tick counter, incremented on each timer overflow and 00081 * cleared on each edge detection on the infrared signal. 00082 */ 00083 static u_short irticks; 00084 00085 /* 00086 * Number of bits received from infrared decoder. 00087 */ 00088 static u_char irbitnum; 00089 00093 SIGNAL(SIG_OVERFLOW2) 00094 { 00095 /* Set the timer value. */ 00096 outb(TCNT2, IRTIMER_START); 00097 00098 /* 00099 * Increment our tick counter. If it overflows, then wait 00100 * for the next start bit and disable the timer. 00101 */ 00102 if (++irticks == 0) { 00103 irbitnum = 0; 00104 cbi(TIMSK, 6); 00105 } 00106 } 00107 00111 SIGNAL(SIG_INTERRUPT4) 00112 { 00113 static u_short minset; /* Min. length of bit value 1, calculated from start bit. */ 00114 static u_short ccode; /* Current code. */ 00115 static u_short lcode; /* Last code. */ 00116 static u_char ncode; /* Number of equal codes. */ 00117 u_short bitlen = irticks; /* Length of the current bit. */ 00118 00119 irticks = 0; 00120 00121 /* Rising egde marks end of bit. */ 00122 if (inb(IR_SIGNAL_PIN) & _BV(IR_SIGNAL_BIT)) { 00123 /* Start bit. */ 00124 if (irbitnum++ == 0) { 00125 ccode = 0; 00126 minset = bitlen / 3; 00127 } 00128 /* Data bits. */ 00129 else { 00130 /* If its length is greater than a third of the start bit, 00131 then we assume this bit set. */ 00132 if (bitlen >= minset) 00133 ccode |= _BV(12); 00134 ccode >>= 1; 00135 /* All data bits collected? */ 00136 if (irbitnum > 12) { 00137 cbi(TIMSK, 6); 00138 irbitnum = 0; 00139 if (ncode++) { 00140 if (lcode != ccode) 00141 ncode = 0; 00142 /* If we have two equal codes, pass it to the 00143 application. */ 00144 else if (ncode > 1) { 00145 ncode = 0; 00146 nut_ircode = ccode; 00147 NutEventPostFromIrq(&nut_irqueue); 00148 } 00149 } else 00150 lcode = ccode; 00151 } 00152 } 00153 } 00154 /* Falling edges mark the start of a bit. Enable timer 00155 overflow interrupts. */ 00156 else if (irbitnum == 0) { 00157 sbi(TIMSK, 6); 00158 } 00159 00160 } 00161 00165 int NutIrInitSony(void) 00166 { 00167 NutEnterCritical(); 00168 /* 00169 * Initialize timer 2 and enable overflow interrupts. 00170 */ 00171 outb(TCNT2, IRTIMER_START); 00172 outb(TCCR2, IRTIMER_SCALE); 00173 sbi(TIMSK, 6); 00174 00175 /* 00176 * Enable infrared decoder interrupts on both edges. 00177 */ 00178 cbi(IR_SIGNAL_DDR, IR_SIGNAL_BIT); 00179 sbi(EICR, 0); 00180 cbi(EICR, 1); 00181 sbi(EIMSK, IR_SIGNAL_BIT); 00182 00183 NutExitCritical(); 00184 00185 return 0; 00186 } 00187