RC5 compatible receiver class, interrupt driven

Dependencies:   mbed

Committer:
pwheels
Date:
Mon Feb 28 08:52:01 2011 +0000
Revision:
0:e3f62f54fa40
replaces RC5_Receiver, has been removed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pwheels 0:e3f62f54fa40 1 /*
pwheels 0:e3f62f54fa40 2 Copyright (c) 2011 Pro-Serv
pwheels 0:e3f62f54fa40 3
pwheels 0:e3f62f54fa40 4 Permission is hereby granted, free of charge, to any person obtaining a copy
pwheels 0:e3f62f54fa40 5 of this software and associated documentation files (the "Software"), to deal
pwheels 0:e3f62f54fa40 6 in the Software without restriction, including without limitation the rights
pwheels 0:e3f62f54fa40 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pwheels 0:e3f62f54fa40 8 copies of the Software, and to permit persons to whom the Software is
pwheels 0:e3f62f54fa40 9 furnished to do so, subject to the following conditions:
pwheels 0:e3f62f54fa40 10
pwheels 0:e3f62f54fa40 11 The above copyright notice and this permission notice shall be included in
pwheels 0:e3f62f54fa40 12 all copies or substantial portions of the Software.
pwheels 0:e3f62f54fa40 13
pwheels 0:e3f62f54fa40 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pwheels 0:e3f62f54fa40 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pwheels 0:e3f62f54fa40 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pwheels 0:e3f62f54fa40 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pwheels 0:e3f62f54fa40 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pwheels 0:e3f62f54fa40 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pwheels 0:e3f62f54fa40 20 THE SOFTWARE.
pwheels 0:e3f62f54fa40 21
pwheels 0:e3f62f54fa40 22 Usage and assumptions:
pwheels 0:e3f62f54fa40 23 Based on TSOP 1738 IR device, Vcc to 5Volt, Gnd to Gnd, Out has pull-up of 10K
pwheels 0:e3f62f54fa40 24 to Vcc and Out has diode (Cathode to Out) connected to pin (p16) (Anode to p16)
pwheels 0:e3f62f54fa40 25 and pin (p16) has mode PullUp
pwheels 0:e3f62f54fa40 26
pwheels 0:e3f62f54fa40 27 This will allow a "standard" RC5 device to be used to read it transmitted codes.
pwheels 0:e3f62f54fa40 28 Still work in progress (in due time) to add newer rc6 devices
pwheels 0:e3f62f54fa40 29
pwheels 0:e3f62f54fa40 30 Excellent source on RC5 protocol: http://www.ustr.net/infrared/infrared1.shtml
pwheels 0:e3f62f54fa40 31 */
pwheels 0:e3f62f54fa40 32
pwheels 0:e3f62f54fa40 33 #ifndef MBED_H
pwheels 0:e3f62f54fa40 34 #include "mbed.h"
pwheels 0:e3f62f54fa40 35 #endif
pwheels 0:e3f62f54fa40 36
pwheels 0:e3f62f54fa40 37 #ifndef RC5_PIN_ASSTERED
pwheels 0:e3f62f54fa40 38 #define RC5_PIN_ASSTERED 1
pwheels 0:e3f62f54fa40 39 #endif
pwheels 0:e3f62f54fa40 40
pwheels 0:e3f62f54fa40 41 #ifndef RC5_DELAY_PERIOD
pwheels 0:e3f62f54fa40 42 #define RC5_DELAY_PERIOD 4752
pwheels 0:e3f62f54fa40 43 #endif
pwheels 0:e3f62f54fa40 44
pwheels 0:e3f62f54fa40 45 #ifndef RC5_INTERVAL_PERIOD
pwheels 0:e3f62f54fa40 46 #define RC5_INTERVAL_PERIOD 1728
pwheels 0:e3f62f54fa40 47 #endif
pwheels 0:e3f62f54fa40 48
pwheels 0:e3f62f54fa40 49 #ifndef RC5_FINSISH_PERIOD
pwheels 0:e3f62f54fa40 50 #define RC5_FINISH_PERIOD 65000
pwheels 0:e3f62f54fa40 51 #endif
pwheels 0:e3f62f54fa40 52
pwheels 0:e3f62f54fa40 53 #ifndef RC5_SAMPLE_COUNT
pwheels 0:e3f62f54fa40 54 #define RC5_SAMPLE_COUNT 14
pwheels 0:e3f62f54fa40 55 #endif
pwheels 0:e3f62f54fa40 56
pwheels 0:e3f62f54fa40 57 namespace RC5 {
pwheels 0:e3f62f54fa40 58
pwheels 0:e3f62f54fa40 59 /* RC5Detect adds a RC5 compatible data entry using InterruptIn & DigitalIn.
pwheels 0:e3f62f54fa40 60 *
pwheels 0:e3f62f54fa40 61 * This is done by sampling the specified pin at specific interrupt driven intervals
pwheels 0:e3f62f54fa40 62 and sampling the actual pin level
pwheels 0:e3f62f54fa40 63 */
pwheels 0:e3f62f54fa40 64
pwheels 0:e3f62f54fa40 65 class RC5Detect {
pwheels 0:e3f62f54fa40 66
pwheels 0:e3f62f54fa40 67 protected:
pwheels 0:e3f62f54fa40 68 InterruptIn *_int;
pwheels 0:e3f62f54fa40 69 DigitalIn *_inp;
pwheels 0:e3f62f54fa40 70 DigitalOut *_out; // out was added temporary for debugging
pwheels 0:e3f62f54fa40 71 Ticker *_ticker;
pwheels 0:e3f62f54fa40 72 Timeout *_delay;
pwheels 0:e3f62f54fa40 73 Timeout *_finish;
pwheels 0:e3f62f54fa40 74 int _stepCount;
pwheels 0:e3f62f54fa40 75 int _pulseCount;
pwheels 0:e3f62f54fa40 76 int _sampleInterval;
pwheels 0:e3f62f54fa40 77 int _sampleDelay;
pwheels 0:e3f62f54fa40 78 int _sampleFinish;
pwheels 0:e3f62f54fa40 79 int _assertValue;
pwheels 0:e3f62f54fa40 80 int _rc5Data;
pwheels 0:e3f62f54fa40 81 int _rc5Cmd;
pwheels 0:e3f62f54fa40 82 int _rc5Adr;
pwheels 0:e3f62f54fa40 83 int _rc5Ready;
pwheels 0:e3f62f54fa40 84
pwheels 0:e3f62f54fa40 85 /* initialise class
pwheels 0:e3f62f54fa40 86 *
pwheels 0:e3f62f54fa40 87 * @param PinName p is a valid pin for InterruptIn/DigitalIn &
pwheels 0:e3f62f54fa40 88 * @param PinMode m is a mode the InterruptIn/DigitalIn should use.
pwheels 0:e3f62f54fa40 89 */
pwheels 0:e3f62f54fa40 90 void init(PinName p, PinMode m) {
pwheels 0:e3f62f54fa40 91 _sampleInterval = RC5_INTERVAL_PERIOD;
pwheels 0:e3f62f54fa40 92 _sampleDelay = RC5_DELAY_PERIOD;
pwheels 0:e3f62f54fa40 93 _sampleFinish = RC5_FINISH_PERIOD;
pwheels 0:e3f62f54fa40 94 _assertValue = RC5_PIN_ASSTERED;
pwheels 0:e3f62f54fa40 95 _int = new InterruptIn( p );
pwheels 0:e3f62f54fa40 96 _inp = new DigitalIn( p );
pwheels 0:e3f62f54fa40 97 //_out = new DigitalOut( x ); // out to be added temporary for debugging
pwheels 0:e3f62f54fa40 98 //_out->write(1); // same, set high level
pwheels 0:e3f62f54fa40 99 _int->mode( m );
pwheels 0:e3f62f54fa40 100 _inp->mode( m );
pwheels 0:e3f62f54fa40 101 _stepCount = 0;
pwheels 0:e3f62f54fa40 102 _ticker = new Ticker;
pwheels 0:e3f62f54fa40 103 _delay = new Timeout;
pwheels 0:e3f62f54fa40 104 _finish = new Timeout;
pwheels 0:e3f62f54fa40 105 _int->fall(this, &RC5Detect::isr_int);
pwheels 0:e3f62f54fa40 106 }
pwheels 0:e3f62f54fa40 107
pwheels 0:e3f62f54fa40 108 public:
pwheels 0:e3f62f54fa40 109
pwheels 0:e3f62f54fa40 110 friend class Ticker;
pwheels 0:e3f62f54fa40 111 friend class Timeout;
pwheels 0:e3f62f54fa40 112
pwheels 0:e3f62f54fa40 113 /* PinDetect constructor(s) & overloading */
pwheels 0:e3f62f54fa40 114 RC5Detect() { error("Provide a valid PinName"); }
pwheels 0:e3f62f54fa40 115
pwheels 0:e3f62f54fa40 116 RC5Detect(PinName p) {
pwheels 0:e3f62f54fa40 117 init( p, PullUp);
pwheels 0:e3f62f54fa40 118 }
pwheels 0:e3f62f54fa40 119
pwheels 0:e3f62f54fa40 120 RC5Detect(PinName p, PinMode m) {
pwheels 0:e3f62f54fa40 121 init( p, m );
pwheels 0:e3f62f54fa40 122 }
pwheels 0:e3f62f54fa40 123
pwheels 0:e3f62f54fa40 124 /* PinDetect destructor */
pwheels 0:e3f62f54fa40 125 ~RC5Detect() {
pwheels 0:e3f62f54fa40 126 if ( _ticker ) delete( _ticker );
pwheels 0:e3f62f54fa40 127 if ( _delay ) delete( _delay );
pwheels 0:e3f62f54fa40 128 if ( _finish ) delete( _finish );
pwheels 0:e3f62f54fa40 129 if ( _inp ) delete( _inp );
pwheels 0:e3f62f54fa40 130 if ( _int ) delete( _int );
pwheels 0:e3f62f54fa40 131 }
pwheels 0:e3f62f54fa40 132
pwheels 0:e3f62f54fa40 133 /* Set the sampling delay time in microseconds. */
pwheels 0:e3f62f54fa40 134 void setDelaySample(int i = RC5_DELAY_PERIOD) { _sampleDelay = i; }
pwheels 0:e3f62f54fa40 135
pwheels 0:e3f62f54fa40 136 /* Set the sampling interval time in microseconds. */
pwheels 0:e3f62f54fa40 137 void setIntervalSample(int i = RC5_INTERVAL_PERIOD) { _sampleInterval = i; }
pwheels 0:e3f62f54fa40 138
pwheels 0:e3f62f54fa40 139 /* Set the sampling finish time in microseconds. */
pwheels 0:e3f62f54fa40 140 void setFinishSample(int i = RC5_FINISH_PERIOD) { _sampleFinish = i; }
pwheels 0:e3f62f54fa40 141
pwheels 0:e3f62f54fa40 142 /* Set the value used as assert. */ /* not yet implemented */
pwheels 0:e3f62f54fa40 143 void setAssertValue (int i = RC5_PIN_ASSTERED) { _assertValue = i & 1; }
pwheels 0:e3f62f54fa40 144
pwheels 0:e3f62f54fa40 145 void mode(PinMode m) { _inp->mode( m ); }
pwheels 0:e3f62f54fa40 146
pwheels 0:e3f62f54fa40 147 bool getReadyState(void) { return _rc5Ready; }
pwheels 0:e3f62f54fa40 148
pwheels 0:e3f62f54fa40 149 void setReadyState(int i) { _rc5Ready = i & 1; }
pwheels 0:e3f62f54fa40 150
pwheels 0:e3f62f54fa40 151 int getRC5Address(void) { return _rc5Adr; }
pwheels 0:e3f62f54fa40 152
pwheels 0:e3f62f54fa40 153 int getRC5Command(void) { return _rc5Cmd; }
pwheels 0:e3f62f54fa40 154
pwheels 0:e3f62f54fa40 155 protected:
pwheels 0:e3f62f54fa40 156 /* The interrupt service routines are: pin status, delay, interval and finish
pwheels 0:e3f62f54fa40 157 * the pin status is intended to capture start of transmission */
pwheels 0:e3f62f54fa40 158 void isr_int(void) {
pwheels 0:e3f62f54fa40 159 if (_stepCount == 0) { // first trigger event?
pwheels 0:e3f62f54fa40 160 _stepCount++;
pwheels 0:e3f62f54fa40 161 _rc5Ready = _rc5Cmd = _rc5Adr = 0; //
pwheels 0:e3f62f54fa40 162 _delay->attach_us(this, &RC5Detect::isr_delay, _sampleDelay);
pwheels 0:e3f62f54fa40 163 _finish->attach_us(this, &RC5Detect::isr_finish, _sampleFinish);
pwheels 0:e3f62f54fa40 164 }
pwheels 0:e3f62f54fa40 165 _pulseCount++;
pwheels 0:e3f62f54fa40 166 }
pwheels 0:e3f62f54fa40 167
pwheels 0:e3f62f54fa40 168 /* The delay is intended to hold of data sampling untill we get meaningfull bits */
pwheels 0:e3f62f54fa40 169 void isr_delay() {
pwheels 0:e3f62f54fa40 170 _ticker->attach_us( this, &RC5Detect::isr_interval, _sampleInterval );
pwheels 0:e3f62f54fa40 171 _rc5Data = _inp->read() & 0x01; // add first bit of RC5
pwheels 0:e3f62f54fa40 172 //_out->write(0);
pwheels 0:e3f62f54fa40 173 //_out->write(1);
pwheels 0:e3f62f54fa40 174 }
pwheels 0:e3f62f54fa40 175
pwheels 0:e3f62f54fa40 176 /* The interval will sample all successive rc5 address and command bits */
pwheels 0:e3f62f54fa40 177 void isr_interval() {
pwheels 0:e3f62f54fa40 178 if (_stepCount == 10) {
pwheels 0:e3f62f54fa40 179 _ticker->detach(); // sampling is done now !
pwheels 0:e3f62f54fa40 180 }
pwheels 0:e3f62f54fa40 181 _rc5Data = (_rc5Data << 1) + (_inp->read() & 0x01); // shift partial and add next bit
pwheels 0:e3f62f54fa40 182 _stepCount++;
pwheels 0:e3f62f54fa40 183 //_out->write(0);
pwheels 0:e3f62f54fa40 184 //_out->write(1);
pwheels 0:e3f62f54fa40 185 }
pwheels 0:e3f62f54fa40 186
pwheels 0:e3f62f54fa40 187 /* The finish is intended to do cleanup at end of frame and prepare for next frame */
pwheels 0:e3f62f54fa40 188 void isr_finish() {
pwheels 0:e3f62f54fa40 189 if ((_stepCount == 11) && (_pulseCount > 10)) {
pwheels 0:e3f62f54fa40 190 _rc5Cmd = _rc5Data & 0x3f; // get command part of RC5
pwheels 0:e3f62f54fa40 191 _rc5Adr = (_rc5Data >> 6) & 0x1f; // get address part of RC5
pwheels 0:e3f62f54fa40 192 _rc5Ready = 1;
pwheels 0:e3f62f54fa40 193 }
pwheels 0:e3f62f54fa40 194 _pulseCount = _stepCount = _rc5Data = 0; // init for next bit stream
pwheels 0:e3f62f54fa40 195 }
pwheels 0:e3f62f54fa40 196
pwheels 0:e3f62f54fa40 197 };
pwheels 0:e3f62f54fa40 198
pwheels 0:e3f62f54fa40 199 }; // namespace RC5 ends.
pwheels 0:e3f62f54fa40 200
pwheels 0:e3f62f54fa40 201 using namespace RC5;
pwheels 0:e3f62f54fa40 202