-
Notifications
You must be signed in to change notification settings - Fork 0
/
ir_JVC.cpp
131 lines (119 loc) · 4.95 KB
/
ir_JVC.cpp
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2015 Kristian Lauszus
// Copyright 2017 David Conran
/// @file
/// @brief Support for JVC protocols.
/// Originally added by Kristian Lauszus
/// Thanks to zenwheel and other people at the original blog post.
/// @see http://www.sbprojects.net/knowledge/ir/jvc.php
// Supports:
// Brand: JVC, Model: PTU94023B remote
#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// Constants
const uint16_t kJvcTick = 75;
const uint16_t kJvcHdrMarkTicks = 112;
const uint16_t kJvcHdrMark = kJvcHdrMarkTicks * kJvcTick;
const uint16_t kJvcHdrSpaceTicks = 56;
const uint16_t kJvcHdrSpace = kJvcHdrSpaceTicks * kJvcTick;
const uint16_t kJvcBitMarkTicks = 7;
const uint16_t kJvcBitMark = kJvcBitMarkTicks * kJvcTick;
const uint16_t kJvcOneSpaceTicks = 23;
const uint16_t kJvcOneSpace = kJvcOneSpaceTicks * kJvcTick;
const uint16_t kJvcZeroSpaceTicks = 7;
const uint16_t kJvcZeroSpace = kJvcZeroSpaceTicks * kJvcTick;
const uint16_t kJvcRptLengthTicks = 800;
const uint16_t kJvcRptLength = kJvcRptLengthTicks * kJvcTick;
const uint16_t kJvcMinGapTicks =
kJvcRptLengthTicks -
(kJvcHdrMarkTicks + kJvcHdrSpaceTicks +
kJvcBits * (kJvcBitMarkTicks + kJvcOneSpaceTicks) + kJvcBitMarkTicks);
const uint16_t kJvcMinGap = kJvcMinGapTicks * kJvcTick;
#if SEND_JVC
/// Send a JVC formatted message.
/// Status: STABLE / Working.
/// @param[in] data The message to be sent.
/// @param[in] nbits The number of bits of message to be sent.
/// @param[in] repeat The number of times the command is to be repeated.
/// @see http://www.sbprojects.net/knowledge/ir/jvc.php
void IRsend::sendJVC(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Set 38kHz IR carrier frequency & a 1/3 (33%) duty cycle.
enableIROut(38, 33);
IRtimer usecs = IRtimer();
// Header
// Only sent for the first message.
mark(kJvcHdrMark);
space(kJvcHdrSpace);
// We always send the data & footer at least once, hence '<= repeat'.
for (uint16_t i = 0; i <= repeat; i++) {
sendGeneric(0, 0, // No Header
kJvcBitMark, kJvcOneSpace, kJvcBitMark, kJvcZeroSpace,
kJvcBitMark, kJvcMinGap, data, nbits, 38, true,
0, // Repeats are handles elsewhere.
33);
// Wait till the end of the repeat time window before we send another code.
uint32_t elapsed = usecs.elapsed();
// Avoid potential unsigned integer underflow.
// e.g. when elapsed > kJvcRptLength.
if (elapsed < kJvcRptLength) space(kJvcRptLength - elapsed);
usecs.reset();
}
}
/// Calculate the raw JVC data based on address and command.
/// Status: STABLE / Works fine.
/// @param[in] address An 8-bit address value.
/// @param[in] command An 8-bit command value.
/// @return A raw JVC message code, suitable for sendJVC()..
/// @see http://www.sbprojects.net/knowledge/ir/jvc.php
uint16_t IRsend::encodeJVC(uint8_t address, uint8_t command) {
return reverseBits((command << 8) | address, 16);
}
#endif // SEND_JVC
#if DECODE_JVC
/// Decode the supplied JVC message.
/// Status: Stable / Known working.
/// @param[in,out] results Ptr to the data to decode & where to store the result
/// @param[in] offset The starting index to use when attempting to decode the
/// raw data. Typically/Defaults to kStartOffset.
/// @param[in] nbits The number of data bits to expect.
/// @param[in] strict Flag indicating if we should perform strict matching.
/// @return True if it can decode it, false if it can't.
/// @note JVC repeat codes don't have a header.
/// @see http://www.sbprojects.net/knowledge/ir/jvc.php
bool IRrecv::decodeJVC(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (strict && nbits != kJvcBits)
return false; // Must be called with the correct nr. of bits.
if (results->rawlen <= 2 * nbits + kFooter - 1 + offset)
return false; // Can't possibly be a valid JVC message.
uint64_t data = 0;
bool isRepeat = true;
// Header
// (Optional as repeat codes don't have the header)
if (matchMark(results->rawbuf[offset], kJvcHdrMark)) {
isRepeat = false;
offset++;
if (results->rawlen < 2 * nbits + 4)
return false; // Can't possibly be a valid JVC message with a header.
if (!matchSpace(results->rawbuf[offset++], kJvcHdrSpace)) return false;
}
// Data + Footer
if (!matchGeneric(results->rawbuf + offset, &data,
results->rawlen - offset, nbits,
0, 0,
kJvcBitMark, kJvcOneSpace,
kJvcBitMark, kJvcZeroSpace,
kJvcBitMark, kJvcMinGap, true)) return false;
// Success
results->decode_type = JVC;
results->bits = nbits;
results->value = data;
// command & address are transmitted LSB first, so we need to reverse them.
results->address = reverseBits(data >> 8, 8); // The first 8 bits sent.
results->command = reverseBits(data & 0xFF, 8); // The last 8 bits sent.
results->repeat = isRepeat;
return true;
}
#endif // DECODE_JVC