A replacement for InterruptIn that debounces the interrupt.

Dependents:   D7A_Demo-Get-started CVtoOSCConverter EE3501keypad D7A_Localisation ... more

Fork of DebouncedInterrupt by Anil Kandangath

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DebouncedInterrupt.cpp Source File

DebouncedInterrupt.cpp

00001 /**
00002 * DebouncedInterrupt.cpp
00003 **/
00004 #include "DebouncedInterrupt.h"
00005 
00006 
00007 DebouncedInterrupt::DebouncedInterrupt(PinName pin)
00008 {
00009     _in = new InterruptIn(pin);
00010     _din = new DigitalIn(pin, PullUp);
00011     _timeout = new Timeout;
00012 }
00013 
00014 DebouncedInterrupt::~DebouncedInterrupt()
00015 {
00016     delete _in;
00017     delete _din;
00018     delete _timeout;
00019 }
00020 
00021 void DebouncedInterrupt::attach(void (*fptr)(void), const gpio_irq_event trigger, const uint32_t debounce_ms, bool immediate)
00022 {
00023     if(fptr) {
00024         _callback = callback(fptr);
00025         _last_bounce_count = _bounce_count = 0;
00026         _debounce_us = 1000*debounce_ms;
00027         _trigger = trigger;
00028         _timeout_expired = true;
00029         _immediate = immediate;
00030         
00031         switch(trigger)
00032         {
00033             case IRQ_RISE:
00034                 _in->rise(callback(this, &DebouncedInterrupt::_onInterrupt));
00035                 break;
00036             case IRQ_FALL:
00037                 _in->fall(callback(this, &DebouncedInterrupt::_onInterrupt));
00038                 break;
00039             case IRQ_NONE:
00040                 reset(); // Unexpected. Clear callbacks.
00041                 break;
00042         }
00043     } else {
00044         reset();
00045     }
00046 }
00047 
00048 void DebouncedInterrupt::reset()
00049 {
00050     _timeout->detach();
00051     _timeout_expired = true;
00052 }
00053 
00054 unsigned int DebouncedInterrupt::get_bounce()
00055 {
00056     return _last_bounce_count;
00057 }
00058 
00059 void DebouncedInterrupt::_onCallback()
00060 {
00061     _last_bounce_count = _bounce_count;
00062     _bounce_count = 0;
00063     if (!_immediate) {
00064         if (_din->read() == (_trigger==IRQ_RISE)) {
00065             _callback.call();
00066         }
00067     }
00068     _timeout_expired = true;
00069 }
00070 
00071 void DebouncedInterrupt::_onInterrupt()
00072 {
00073     _bounce_count++;
00074 
00075     if (_immediate) {
00076         if (_timeout_expired) {
00077             _timeout_expired = false;
00078             _callback.call();
00079             _timeout->attach_us(callback(this, &DebouncedInterrupt::_onCallback), _debounce_us);
00080         }
00081     }
00082     else {
00083         _timeout->attach_us(callback(this, &DebouncedInterrupt::_onCallback), _debounce_us);
00084     }
00085 }