forked from bengtmartensson/Infrared4Arduino
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRc5Renderer.cpp
66 lines (57 loc) · 2.17 KB
/
Rc5Renderer.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
// {36k,msb,889}<1,-1|-1,1>((1:1,~F:1:6,T:1,D:5,F:6,^114m)+,T=1-T)[T@:0..1=0,D:0..31,F:0..127]
#include "Rc5Renderer.h"
// NOTE: writing intro[i++] = ... produces wrong result, compiler bug?
// (Adding a print statement immediately after, and it works :-~)
// So let's write intro[i] = ...; i++ at least for now.
uint8_t Rc5Renderer::T = 1;
const IrSignal *Rc5Renderer::newIrSignal(unsigned int D, unsigned int F) {
T = ! T;
return newIrSignal(D, F, T);
}
const IrSignal *Rc5Renderer::newIrSignal(unsigned int D, unsigned int F, unsigned int T) {
unsigned int index = 0U;
int pending = 0;
microseconds_t *repeat = new microseconds_t[28];
emit(1U, index, pending, repeat);
emit(((~F) & 0x40U) >> 6U, index, pending, repeat);
emit(T & 1U, index, pending, repeat);
emitMsb(D, 5U, index, pending, repeat);
emitMsb(F, 6U, index, pending, repeat);
emitEnd(index, pending, repeat);
IrSequence *intro = new IrSequence();
IrSequence *repeatSequence = new IrSequence(repeat, index, true);
IrSequence *ending = new IrSequence();
return new IrSignal(*intro, *repeatSequence, *ending, frequency);
}
//const IrSignal& Rc5Renderer::render() const {
// return *(new IrSignal(frequency, 0, index, 0, NULL, repeat, NULL));
//}
void Rc5Renderer::emitMsb(unsigned int x, unsigned int length,
unsigned int& index, int& pending, microseconds_t *repeat) {
unsigned int mask = 1U << (length - 1U);
while (mask != 0U) {
emit((x & mask) != 0, index, pending, repeat);
mask >>= 1U;
}
}
void Rc5Renderer::emit(unsigned int x, unsigned int& index, int& pending,
microseconds_t *repeat) {
if (pending == 0) {
// First, do nothing, just stuff in pending.
} else if ((pending > 0) == ((x & 1) != 0)) {
repeat[index] = timebase;
index++;
repeat[index] = timebase;
index++;
} else {
repeat[index] = 2 * timebase;
index++;
}
pending = (x & 1U) ? 1 : -1;
}
void Rc5Renderer::emitEnd(unsigned int& index, int& pending, microseconds_t *repeat) {
if (pending > 0) {
repeat[index] = timebase; index++;
}
repeat[index] = 0xFFFF; index++;
}