Редизайн на основе текущей ветки мейнстрима + новые устройства.
[rtl-433.git] / src / devices / generic_remote.c
1 /* Generic remotes and sensors using PT2260/PT2262 SC2260/SC2262 EV1527 protocol
2  *
3  * Tested devices:
4  * SC2260
5  * EV1527
6  *
7  * Copyright (C) 2015 Tommy Vestermark
8  * Copyright (C) 2015 nebman
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  */
14 #include "rtl_433.h"
15 #include "pulse_demod.h"
16 #include "data.h"
17 #include "util.h"
18
19 static int generic_remote_callback(bitbuffer_t *bitbuffer) {
20         bitrow_t *bb = bitbuffer->bb;
21         uint8_t *b = bb[0];
22         data_t *data;
23         char time_str[LOCAL_TIME_BUFLEN];
24         char tristate[23];
25         char *p = tristate;
26
27         //invert bits, short pulse is 0, long pulse is 1
28         b[0] = ~b[0];
29         b[1] = ~b[1];
30         b[2] = ~b[2];
31
32         unsigned bits = bitbuffer->bits_per_row[0];
33
34         // Validate package
35         if ((bits == 25)
36          && (b[3] & 0x80)       // Last bit (MSB here) is always 1
37          && (b[0] || b[1])      // Reduce false positives. ID 0x0000 not supported
38          && (b[2])      // Reduce false positives. CMD 0x00 not supported
39         ) {
40
41                 uint32_t ID_16b = b[0] << 8 | b[1];
42                 unsigned char CMD_8b = b[2];
43
44 //              fprintf(stdout, "Generic remote keypress / sensor\n");
45 //              fprintf(stdout, "ID 16bit = 0x%04X\n", ID_16b);
46 //              fprintf(stdout, "CMD 8bit = 0x%02X\n", CMD_8b);
47
48
49                 // output tristate coding
50
51                 uint32_t FULL = b[0] << 16 | b[1] << 8 | b[2];
52                 char c;
53
54 //              fprintf(stdout, "TRISTATE = ");
55                 for (signed char i=22; i>=0; i-=2) {
56
57                         switch ((FULL>>i) & 0x03) {
58                                 case 0x00:      c = '0'; break;
59                                 case 0x01:      c = 'F'; break;
60                                 case 0x02:      c = '!'; break; // tristate 10 is invalid code for SC226x but valid in EV1527
61                                 case 0x03:      c = '1'; break;
62                                 default:        c = '?'; break; // not possible anyway
63                         }
64                         *p++=c;
65                         *p = '\0';
66
67
68                         //fputc(c, stdout);
69                 }
70 //              fprintf(stdout, "\n");
71                 local_time_str(0, time_str);
72
73 //              fprintf(stdout, "ID 16bit = 0x%04X\n", ID_16b);
74 //              fprintf(stdout, "CMD 8bit = 0x%02X\n", CMD_8b);
75
76                 data = data_make(
77                         "time",         "",             DATA_STRING, time_str,
78                         "model",        "",             DATA_STRING, "Generic Remote",
79                         "id",           "House Code",   DATA_INT, ID_16b,
80                         "cmd",          "Command",      DATA_INT, CMD_8b,
81                         "tristate",     "Tri-State",    DATA_STRING, tristate,
82                       NULL);
83
84                 data_acquired_handler(data);
85
86
87                 return 1;
88         }
89         return 0;
90 }
91
92
93 PWM_Precise_Parameters pwm_precise_parameters_generic = {
94         .pulse_tolerance        = 50,
95         .pulse_sync_width       = 0,    // No sync bit used
96 };
97
98 r_device generic_remote = {
99         .name                   = "Generic Remote SC226x EV1527",
100         .modulation             = OOK_PULSE_PWM_PRECISE,
101         .short_limit    = 464,
102         .long_limit             = 1404,
103         .reset_limit    = 1800,
104         .json_callback  = &generic_remote_callback,
105         .disabled               = 0,
106         .demod_arg              = (uintptr_t)&pwm_precise_parameters_generic,
107 };