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$ 00036 * Revision 1.2 2008/08/11 06:59:17 haraldkipp 00037 * BSD types replaced by stdint types (feature request #1282721). 00038 * 00039 * Revision 1.1 2005/07/26 18:02:27 haraldkipp 00040 * Moved from dev. 00041 * 00042 * Revision 1.3 2005/01/28 12:13:14 freckle 00043 * changed NutEventPostFromIRQ into NutEventPostFromIrq 00044 * 00045 * Revision 1.2 2004/03/18 18:41:18 haraldkipp 00046 * Bugfix. Now works with ICCAVR 00047 * 00048 * Revision 1.1 2003/07/21 18:07:54 haraldkipp 00049 * Sony infrared remote control driver added 00050 * 00051 */ 00052 00053 #include <cfg/medianut.h> 00054 #include <sys/atom.h> 00055 #include <sys/event.h> 00056 00057 #ifdef __IMAGECRAFT__ 00058 #pragma interrupt_handler SIG_INTERRUPT4:iv_INT4 00059 #pragma interrupt_handler SIG_OVERFLOW2:iv_TIMER2_OVF 00060 #endif 00061 00066 00067 #include <dev/irsony.h> 00068 00069 #define IRTIMER_START 0xF0 00070 #define IRTIMER_SCALE 0x01 00071 00075 long nut_ircode; 00076 00080 HANDLE nut_irqueue; 00081 00082 /* 00083 * Tick counter, incremented on each timer overflow and 00084 * cleared on each edge detection on the infrared signal. 00085 */ 00086 static uint16_t irticks; 00087 00088 /* 00089 * Number of bits received from infrared decoder. 00090 */ 00091 static uint8_t irbitnum; 00092 00096 SIGNAL(SIG_OVERFLOW2) 00097 { 00098 /* Set the timer value. */ 00099 outb(TCNT2, IRTIMER_START); 00100 00101 /* 00102 * Increment our tick counter. If it overflows, then wait 00103 * for the next start bit and disable the timer. 00104 */ 00105 if (++irticks == 0) { 00106 irbitnum = 0; 00107 cbi(TIMSK, 6); 00108 } 00109 } 00110 00114 SIGNAL(SIG_INTERRUPT4) 00115 { 00116 static uint16_t minset; /* Min. length of bit value 1, calculated from start bit. */ 00117 static uint16_t ccode; /* Current code. */ 00118 static uint16_t lcode; /* Last code. */ 00119 static uint8_t ncode; /* Number of equal codes. */ 00120 uint16_t bitlen = irticks; /* Length of the current bit. */ 00121 00122 irticks = 0; 00123 00124 /* Rising egde marks end of bit. */ 00125 if (inb(IR_SIGNAL_PIN) & _BV(IR_SIGNAL_BIT)) { 00126 /* Start bit. */ 00127 if (irbitnum++ == 0) { 00128 ccode = 0; 00129 minset = bitlen / 3; 00130 } 00131 /* Data bits. */ 00132 else { 00133 /* If its length is greater than a third of the start bit, 00134 then we assume this bit set. */ 00135 if (bitlen >= minset) 00136 ccode |= _BV(12); 00137 ccode >>= 1; 00138 /* All data bits collected? */ 00139 if (irbitnum > 12) { 00140 cbi(TIMSK, 6); 00141 irbitnum = 0; 00142 if (ncode++) { 00143 if (lcode != ccode) 00144 ncode = 0; 00145 /* If we have two equal codes, pass it to the 00146 application. */ 00147 else if (ncode > 1) { 00148 ncode = 0; 00149 nut_ircode = ccode; 00150 NutEventPostFromIrq(&nut_irqueue); 00151 } 00152 } else 00153 lcode = ccode; 00154 } 00155 } 00156 } 00157 /* Falling edges mark the start of a bit. Enable timer 00158 overflow interrupts. */ 00159 else if (irbitnum == 0) { 00160 sbi(TIMSK, 6); 00161 } 00162 00163 } 00164 00168 int NutIrInitSony(void) 00169 { 00170 NutEnterCritical(); 00171 /* 00172 * Initialize timer 2 and enable overflow interrupts. 00173 */ 00174 outb(TCNT2, IRTIMER_START); 00175 outb(TCCR2, IRTIMER_SCALE); 00176 sbi(TIMSK, 6); 00177 00178 /* 00179 * Enable infrared decoder interrupts on both edges. 00180 */ 00181 cbi(IR_SIGNAL_DDR, IR_SIGNAL_BIT); 00182 sbi(EICR, 0); 00183 cbi(EICR, 1); 00184 sbi(EIMSK, IR_SIGNAL_BIT); 00185 00186 NutExitCritical(); 00187 00188 return 0; 00189 } 00190