1 /** @file
2     Decoder for UHF Dish Remote Control 6.3.
3 
4     Copyright (C) 2018 David E. Tiller
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11 */
12 /**
13 Decoder for UHF Dish Remote Control 6.3.
14 (tested with genuine Dish remote.)
15 
16 The device uses PPM encoding,
17 0 is encoded as 400 us pulse and 1692 uS gap,
18 1 is encoded as 400 us pulse and 2812 uS gap.
19 The device sends 7 transmissions per button press approx 6000 uS apart.
20 A transmission starts with a 400 uS start bit and a 6000 uS gap.
21 
22 Each packet is 16 bits in length.
23 Packet bits: BBBBBB10 101X1XXX
24 B = Button pressed, big-endian
25 X = unknown, possibly channel
26 */
27 
28 #include "decoder.h"
29 
30 #define MYDEVICE_BITLEN      16
31 #define MYDEVICE_MINREPEATS  3
32 
33 char *button_map[] = {
34 /*  0 */ "Undefined",
35 /*  1 */ "Undefined",
36 /*  2 */ "Swap",
37 /*  3 */ "Undefined",
38 /*  4 */ "Position",
39 /*  5 */ "PIP",
40 /*  6 */ "DVR",
41 /*  7 */ "Undefined",
42 /*  8 */ "Skip Forward",
43 /*  9 */ "Skip Backward",
44 /* 10 */ "Undefined",
45 /* 11 */ "Dish Button",
46 /* 12 */ "Undefined",
47 /* 13 */ "Forward",
48 /* 14 */ "Backward",
49 /* 15 */ "TV Power",
50 /* 16 */ "Reset",
51 /* 17 */ "Undefined",
52 /* 18 */ "Undefined",
53 /* 19 */ "Undefined",
54 /* 20 */ "Undefined",
55 /* 21 */ "Undefined",
56 /* 22 */ "SAT",
57 /* 23 */ "Mute/Volume Up/Volume Down",
58 /* 24 */ "Undefined",
59 /* 25 */ "#/Search",
60 /* 26 */ "*/Format",
61 /* 27 */ "Undefined",
62 /* 28 */ "Undefined",
63 /* 29 */ "Undefined",
64 /* 30 */ "Stop",
65 /* 31 */ "Pause",
66 /* 32 */ "Record",
67 /* 33 */ "Channel Down",
68 /* 34 */ "Undefined",
69 /* 35 */ "Left",
70 /* 36 */ "Recall",
71 /* 37 */ "Channel Up",
72 /* 38 */ "Undefined",
73 /* 39 */ "Right",
74 /* 40 */ "TV/Video",
75 /* 41 */ "View/Live TV",
76 /* 42 */ "Undefined",
77 /* 43 */ "Guide",
78 /* 44 */ "Undefined",
79 /* 45 */ "Cancel",
80 /* 46 */ "Digit 0",
81 /* 47 */ "Select",
82 /* 48 */ "Page Up",
83 /* 49 */ "Digit 9",
84 /* 50 */ "Digit 8",
85 /* 51 */ "Digit 7",
86 /* 52 */ "Menu",
87 /* 53 */ "Digit 6",
88 /* 54 */ "Digit 5",
89 /* 55 */ "Digit 4",
90 /* 56 */ "Page Down",
91 /* 57 */ "Digit 3",
92 /* 58 */ "Digit 2",
93 /* 59 */ "Digit 1",
94 /* 60 */ "Play",
95 /* 61 */ "Dish Power",
96 /* 62 */ "Undefined",
97 /* 63 */ "Info"
98 };
99 
dish_remote_6_3_callback(r_device * decoder,bitbuffer_t * bitbuffer)100 static int dish_remote_6_3_callback(r_device *decoder, bitbuffer_t *bitbuffer)
101 {
102     data_t *data;
103     int r; // a row index
104     uint8_t *b; // bits of a row
105     uint8_t button;
106     char *button_string;
107 
108     if (decoder->verbose > 1) {
109         fprintf(stderr,"dish_remote_6_3_callback callback:\n");
110         bitbuffer_print(bitbuffer);
111     }
112 
113     r = bitbuffer_find_repeated_row(bitbuffer, MYDEVICE_MINREPEATS, MYDEVICE_BITLEN);
114     if (r < 0 || bitbuffer->bits_per_row[r] > MYDEVICE_BITLEN) {
115         return DECODE_ABORT_LENGTH;
116     }
117 
118     b = bitbuffer->bb[r];
119 
120     /* Check fixed bits to prevent misreads */
121     if ((b[0] & 0x03) != 0x02 || (b[1] & 0xe8) != 0xa8) {
122         return DECODE_FAIL_SANITY;
123     }
124 
125     button = b[0] >> 2;
126     button_string = button_map[button];
127 
128     data = data_make(
129             "model", "", DATA_STRING, "Dish-RC63",
130             "button", "", DATA_STRING, button_string,
131             NULL);
132 
133     decoder_output_data(decoder, data);
134 
135     return 1;
136 }
137 
138 static char *output_fields[] = {
139     "model",
140     "button",
141     NULL
142 };
143 
144 r_device dish_remote_6_3 = {
145     .name          = "Dish remote 6.3",
146     .modulation    = OOK_PULSE_PPM,
147     .short_width   = 1692,
148     .long_width    = 2812,
149     .gap_limit     = 4500,
150     .reset_limit   = 9000,
151     .decode_fn     = &dish_remote_6_3_callback,
152     .disabled      = 1,
153     .fields        = output_fields,
154 };
155