This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
rc2007-soccer/source/ct-Bot/mcu/ir-rc5.c

164 lines
4.4 KiB
C
Raw Normal View History

/*
* c't-Bot
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your
* option) any later version.
* This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307, USA.
*
*/
/*! @file ir-rc5.c
* @brief Routinen für die Dekodierung von RC5-Fernbedienungs-Codes
* @author Benjamin Benz (bbe@heise.de)
* @date 20.12.05
*/
// Infos ueber RC6: http://www.xs4all.nl/~sbp/knowledge/ir/rc6.htm
// http://www.xs4all.nl/~sbp/knowledge/ir/ir.htm
// ========================================================================
// RC5 Infrarot-Empf<70>nger
// ========================================================================
#include "ct-Bot.h"
#ifdef MCU
#ifdef IR_AVAILABLE
#include <avr/io.h>
#include "ir-rc5.h"
#include "timer.h"
// -----------------------------------------------------------------------------
// Timing
// -----------------------------------------------------------------------------
#define IR_SAMPLES_PER_BIT 10 /*!< 10 Samples per Bit */
#define IR_SAMPLES_PER_BIT_EARLY 8 /*!< Flanke fr<66>hestens nach 8 Samples */
#define IR_SAMPLES_PER_BIT_LATE 12 /*!< Flanke sp<73>testens nach 12 Samples */
#define IR_SAMPLES_PER_BIT_MIN 3 /*!< Flanke vor 3 Samples -> paket verwerfen */
#define IR_PAUSE_SAMPLES 250 /*!< Startbit ist erst nach 250 Samples ohne */
// Pegel<65>nderung g<>ltig -- eigentlich m<>sste
// man rund 500 Samples abwarten (50 x
// Bitzeit), doch weil der Samplez<65>hler ein
// Byte ist, beschr<68>nken wir uns hier auf ein
// Minimum von 250 Samples
#define IR_PORT PORTB /*!< Port B */
#define IR_DDR DDRB /*!< DDR of Port B */
#define IR_PINR PINB /*!< Port B input */
#define IR_PIN 1 /*!< Pin 1 */
static byte ir_lastsample = 0; /*!< zuletzt gelesenes Sample */
static byte ir_bittimer = 0; /*!< zählt die Aufrufe von ir_isr() */
static uint16 ir_data_tmp = 0; /*!< RC5-Bitstream */
static byte ir_bitcount = 0; /*!< anzahl gelesener bits */
volatile uint16 ir_data = 0; /*!< letztes komplett gelesenes RC5-paket */
/*!
* Interrupt Serviceroutine
* wird ca alle 177.8us aufgerufen
*/
void ir_isr(void) {
// sample lesen
byte sample = 1;
if ((IR_PINR & (1<<IR_PIN)) != 0) {
sample = 0;
}
// bittimer erhoehen (bleibt bei 255 stehen)
if (ir_bittimer<255) {
ir_bittimer++;
}
// flankenerkennung
if ( ir_lastsample != sample) {
if (ir_bittimer<=IR_SAMPLES_PER_BIT_MIN) {
// flanke kommt zu frueh: paket verwerfen
ir_bitcount=0;
} else {
// Startbit
if (ir_bitcount==0) {
if ( (sample==1) && (ir_bittimer>IR_PAUSE_SAMPLES) ) {
// Startbit speichern
ir_data_tmp = 1;
ir_bitcount++;
} else {
// error
ir_data_tmp = 0;
}
// bittimer-reset
ir_bittimer = 0;
// Bits 2..14: nur Flanken innerhalb des Bits beruecksichtigen
} else {
if (ir_bittimer >= IR_SAMPLES_PER_BIT_EARLY) {
if(ir_bittimer<=IR_SAMPLES_PER_BIT_LATE){
// Bit speichern
ir_data_tmp = (ir_data_tmp<<1) | sample;
ir_bitcount++;
} else {
// zu sp<73>t: paket verwerfen
ir_bitcount = 0;
}
// bittimer-reset
ir_bittimer = 0;
}
}
}
} else {
// keine flanke innerhalb bitzeit?
if (ir_bittimer > IR_SAMPLES_PER_BIT_LATE) {
// 14 bits gelesen?
if (ir_bitcount==14) {
ir_data = ir_data_tmp;
}
// paket verwerfen
ir_bitcount = 0;
}
}
// sample im samplepuffer ablegen
ir_lastsample = sample;
}
/*!
* IR-Daten lesen
* @return wert von ir_data, löscht anschliessend ir_data
*/
uint16 ir_read(void) {
uint16 retvalue = ir_data;
ir_data = 0;
return retvalue;
}
/*!
* Init IR-System
*/
void ir_init(void) {
IR_DDR &= ~IR_PIN; // Pin auf Input
IR_PORT |= IR_PIN; // Pullup an
timer_2_init(); // Für IR-Krams
}
#endif
#endif