-
Notifications
You must be signed in to change notification settings - Fork 5
/
otax.c
109 lines (94 loc) · 3 KB
/
otax.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* rf-ctrl - A command-line tool to control 433MHz OOK based devices
* Reversed protocol of OTAX wireless plugs
*
* Copyright (C) 2018 Jean-Christophe Rona <jc@rona.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "rf-ctrl.h"
#define PROTOCOL_NAME "OTAX"
static int otax_format_cmd(uint8_t *data, size_t data_len, uint32_t remote_code, uint32_t device_code, rf_command_t command) {
const int bit_count = 25;
uint8_t raw_cmd; // 4 bits
uint16_t raw_device_code = 0; // 10 bits
uint16_t raw_remote_code = 0; // 10 bits
int i;
if (data_len * 8 < bit_count) {
fprintf(stderr, "%s: data buffer too small (%lu available, %d needed)\n", PROTOCOL_NAME, (unsigned long) data_len, (bit_count + 7)/8);
return -1;
}
switch (command) {
case RF_CMD_OFF:
raw_cmd = 0x01;
break;
case RF_CMD_ON:
raw_cmd = 0x04;
break;
default:
fprintf(stderr, "%s: Unsupported command %d\n", PROTOCOL_NAME, (int) command);
return -1;
}
/*
* Bits of the remote_code remains the same with
* a 1 added after each bit (0 -> 01, 1 -> 11)
*/
for (i = 0; i < 5; i++) {
if (remote_code & (0x1 << i)) {
raw_remote_code |= 0x3 << (2 * i);
} else {
raw_remote_code |= 0x1 << (2 * i);
}
}
/*
* Bits of the device_code are inverted with a
* 0 added before each bit (0 -> 01, 1 -> 00)
*/
for (i = 0; i < 5; i++) {
if (!(device_code & (0x1 << i))) {
raw_device_code |= 0x1 << (2 * i);
}
}
data[0] = (raw_remote_code & 0x3FF) >> 2;
data[1] = ((raw_remote_code & 0x3) << 6) | ((raw_device_code & 0x3FF) >> 4);
data[2] = ((raw_device_code & 0xF) << 4) | (raw_cmd & 0xF);
data[3] = 0;
return bit_count;
}
static struct timing_config otax_timings = {
.start_bit_h_time = 0, // 0 us
.start_bit_l_time = 4860, // 4860 us
.end_bit_h_time = 0, // 0 us
.end_bit_l_time = 0, // 0 us
.data_bit0_h_time = 160, // 160 us
.data_bit0_l_time = 420, // 420 us
.data_bit1_h_time = 420, // 420 us
.data_bit1_l_time = 160, // 160 us
.bit_fmt = RF_BIT_FMT_HL,
.frame_count = 10,
};
struct rf_protocol_driver otax_driver = {
.name = PROTOCOL_NAME,
.cmd_name = "otax",
.timings = &otax_timings,
.format_cmd = &otax_format_cmd,
.remote_code_max = 0x1F,
.device_code_max = 0x1F,
.needed_params = PARAM_REMOTE_ID | PARAM_DEVICE_ID | PARAM_COMMAND,
};