Paul van der Wielen
/
RC5_Device
RC5 compatible receiver class, interrupt driven
RC5Detect.h@0:e3f62f54fa40, 2011-02-28 (annotated)
- 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?
User | Revision | Line number | New 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 |