ir_hasher.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 
00003 #include <pigpio.h>
00004 
00005 #include "ir_hasher.h"
00006 
00007 /*
00008 This code forms a hash over the IR pulses generated by an
00009 IR remote.
00010 
00011 The remote key press is not converted into a code in the manner of
00012 the lirc module.  No attempt is made to decode the type of protocol
00013 used by the remote.  The hash is likely to be unique for different
00014 keys and different remotes but this is not guaranteed.
00015 
00016 This hashing process works for some remotes/protocols but not for
00017 others.  The only way to find out if it works for one or more of
00018 your remotes is to try it and see.
00019 */
00020 
00021 struct _Pi_Hasher_s
00022 {
00023    int gpio;
00024    Pi_Hasher_CB_t callback;
00025    int timeout;
00026    int in_code;
00027    uint32_t hash_val;
00028    int edges;
00029    int t1;
00030    int t2;
00031    int t3;
00032    int t4;
00033 };
00034 
00035 
00036 static uint32_t _hash(uint32_t hv, int old_val, int new_val)
00037 {
00038    int val;
00039 
00040    if      (new_val < (old_val * 0.60)) val = 13;
00041    else if (old_val < (new_val * 0.60)) val = 23;
00042    else                                 val = 2;
00043 
00044    hv ^= val;
00045    hv *= 16777619; /* FNV_PRIME_32 */
00046 
00047    return hv;
00048 }
00049 
00050 static void _cb(int gpio, int level, uint32_t tick, void *user)
00051 {
00052    Pi_Hasher_t * hasher;
00053 
00054    hasher = user;
00055 
00056    if (level != PI_TIMEOUT)
00057    {
00058       if (hasher->in_code == 0)
00059       {
00060          hasher->in_code = 1;
00061 
00062          gpioSetWatchdog(gpio, hasher->timeout);
00063 
00064          hasher->hash_val = 2166136261U; /* FNV_BASIS_32 */
00065 
00066          hasher->edges = 1;
00067 
00068          hasher->t1 = 0;
00069          hasher->t2 = 0;
00070          hasher->t3 = 0;
00071          hasher->t4 = tick;
00072       }
00073       else
00074       {
00075          hasher->edges++;
00076 
00077          hasher->t1 = hasher->t2;
00078          hasher->t2 = hasher->t3;
00079          hasher->t3 = hasher->t4;
00080          hasher->t4 = tick;
00081 
00082          if (hasher->edges > 3)
00083          {
00084             hasher->hash_val =
00085                _hash(hasher->hash_val,
00086                      (hasher->t2)-(hasher->t1),
00087                      (hasher->t4)-(hasher->t3));
00088          }
00089       }
00090    }
00091    else
00092    {
00093       if (hasher->in_code)
00094       {
00095          hasher->in_code = 0;
00096 
00097          gpioSetWatchdog(gpio, 0);
00098 
00099          if (hasher->edges > 12) /* Anything less is probably noise. */
00100          {
00101             (hasher->callback)(hasher->hash_val);
00102          }
00103       }
00104    }
00105 }
00106 
00107 Pi_Hasher_t *Pi_Hasher(int gpio, Pi_Hasher_CB_t callback, int timeout)
00108 {
00109    Pi_Hasher_t *hasher;
00110 
00111    hasher = malloc(sizeof(Pi_Hasher_t));
00112 
00113    hasher->gpio     = gpio;
00114    hasher->callback = callback;
00115    hasher->timeout  = 5;
00116 
00117    hasher->in_code = 0;
00118 
00119    gpioSetMode(gpio, PI_INPUT);
00120    gpioSetAlertFuncEx(gpio, _cb, hasher);
00121 
00122    return hasher;
00123 }
00124 
00125 void Pi_Hasher_cancel(Pi_Hasher_t *hasher)
00126 {
00127    if (hasher)
00128    {
00129       gpioSetAlertFunc(hasher->gpio, 0);
00130 
00131       free(hasher);
00132 
00133       hasher = NULL;
00134    }
00135 }
00136 


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:43:57