5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
23 #define DSM2_SEND_BIND (1 << 7)
24 #define DSM2_SEND_RANGECHECK (1 << 5)
27 uint8_t dsm2BindTimer
= DSM2_BIND_TIMEOUT
;
32 #define FRANCE_BIT 0x10
36 #define BITLEN_DSM2 (8*2) //125000 Baud => 8uS per bit
38 #if defined(PPM_PIN_SERIAL)
39 void putDsm2SerialBit(uint8_t bit
)
41 extmodulePulsesData
.dsm2
.serialByte
>>= 1;
43 extmodulePulsesData
.dsm2
.serialByte
|= 0x80;
45 if (++extmodulePulsesData
.dsm2
.serialBitCount
>= 8) {
46 *extmodulePulsesData
.dsm2
.ptr
++ = extmodulePulsesData
.dsm2
.serialByte
;
47 extmodulePulsesData
.dsm2
.serialBitCount
= 0;
51 void sendByteDsm2(uint8_t b
) // max 10changes 0 10 10 10 10 1
53 putDsm2SerialBit(0); // Start bit
54 for (uint8_t i
=0; i
<8; i
++) { // 8 data Bits
55 putDsm2SerialBit(b
& 1);
59 putDsm2SerialBit(1); // Stop bit
60 putDsm2SerialBit(1); // Stop bit
65 for (int i
=0; i
<16; i
++) {
66 putDsm2SerialBit(1); // 16 extra stop bits
70 void _send_1(uint8_t v
)
72 if (extmodulePulsesData
.dsm2
.index
& 1)
77 *extmodulePulsesData
.dsm2
.ptr
++ = v
- 1;
78 extmodulePulsesData
.dsm2
.index
+= 1;
79 extmodulePulsesData
.dsm2
.rest
-= v
;
82 void sendByteDsm2(uint8_t b
) // max 10 changes 0 10 10 10 10 1
85 uint8_t len
= BITLEN_DSM2
; // max val: 9*16 < 256
86 for (uint8_t i
=0; i
<=8; i
++) { // 8Bits + Stop=1
87 bool nlev
= b
& 1; // lsb first
96 b
= (b
>>1) | 0x80; // shift in stop bit
98 _send_1(len
); // stop bit (len is already BITLEN_DSM2)
103 if (extmodulePulsesData
.dsm2
.index
& 1)
104 *extmodulePulsesData
.dsm2
.ptr
++ = extmodulePulsesData
.dsm2
.rest
;
106 *(extmodulePulsesData
.dsm2
.ptr
- 1) = extmodulePulsesData
.dsm2
.rest
;
110 // This is the data stream to send, prepare after 19.5 mS
111 // Send after 22.5 mS
113 void setupPulsesDSM2()
117 #if defined(PPM_PIN_SERIAL)
118 extmodulePulsesData
.dsm2
.serialByte
= 0 ;
119 extmodulePulsesData
.dsm2
.serialBitCount
= 0 ;
121 extmodulePulsesData
.dsm2
.index
= 0;
122 extmodulePulsesData
.dsm2
.rest
= DSM2_PERIOD
* 2000;
125 extmodulePulsesData
.dsm2
.ptr
= extmodulePulsesData
.dsm2
.pulses
;
127 switch (moduleState
[EXTERNAL_MODULE
].protocol
) {
128 case PROTOCOL_CHANNELS_DSM2_LP45
:
131 case PROTOCOL_CHANNELS_DSM2_DSM2
:
135 dsmDat
[0] = 0x10 | DSMX_BIT
;
139 #if defined(PCBSKY9X)
140 if (dsm2BindTimer
> 0) {
142 if (switchState(SW_DSM2_BIND
)) {
143 moduleState
[EXTERNAL_MODULE
].mode
= MODULE_MODE_BIND
;
144 dsmDat
[0] |= DSM2_SEND_BIND
;
147 else if (moduleState
[EXTERNAL_MODULE
].mode
== MODULE_MODE_RANGECHECK
) {
148 dsmDat
[0] |= DSM2_SEND_RANGECHECK
;
151 moduleState
[EXTERNAL_MODULE
].mode
= 0;
154 if (moduleState
[EXTERNAL_MODULE
].mode
== MODULE_MODE_BIND
) {
155 dsmDat
[0] |= DSM2_SEND_BIND
;
157 else if (moduleState
[EXTERNAL_MODULE
].mode
== MODULE_MODE_RANGECHECK
) {
158 dsmDat
[0] |= DSM2_SEND_RANGECHECK
;
162 dsmDat
[1] = g_model
.header
.modelId
[EXTERNAL_MODULE
]; // DSM2 Header second byte for model match
164 for (int i
=0; i
<DSM2_CHANS
; i
++) {
165 int channel
= g_model
.moduleData
[EXTERNAL_MODULE
].channelsStart
+i
;
166 int value
= channelOutputs
[channel
] + 2*PPM_CH_CENTER(channel
) - 2*PPM_CENTER
;
167 uint16_t pulse
= limit(0, ((value
*13)>>5)+512, 1023);
168 dsmDat
[2+2*i
] = (i
<<2) | ((pulse
>>8)&0x03);
169 dsmDat
[3+2*i
] = pulse
& 0xff;
172 for (int i
=0; i
<14; i
++) {
173 sendByteDsm2(dsmDat
[i
]);