Subversion Repositories FlightCtrl

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1545 LPDunwell 1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
// This code (protocol) is inspired by the RCDSL implementation of Stefan Engelke.
3
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4
/*
5
    Copyright (c) 2008 Stefan Engelke <stefan@tinkerer.eu>
6
 
7
    Permission is hereby granted, free of charge, to any person
8
    obtaining a copy of this software and associated documentation
9
    files (the "Software"), to deal in the Software without
10
    restriction, including without limitation the rights to use, copy,
11
    modify, merge, publish, distribute, sublicense, and/or sell copies
12
    of the Software, and to permit persons to whom the Software is
13
    furnished to do so, subject to the following conditions:
14
 
15
    The above copyright notice and this permission notice shall be
16
    included in all copies or substantial portions of the Software.
17
 
18
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
    DEALINGS IN THE SOFTWARE.
26
*/
27
 
28
/***********************************************************************************************************
29
* FC_JN_RECEIVER by DLP
30
************************************************************************************************************
31
 
32
Connection of receiver to SV1 of FC:
33
TXD <--> pin 3 (RXD1 Atmega644p)
34
RXD <--> pin 4 (TXD1 Atmega644p)
35
 
36
Data is sent at every 20 ms @ 57600 Baud 8-N-1
37
************************************************************************************************************
38
Data Frame Jennic: |0xFF|0xFF|STATUS|CHN|CH0D1|CH0D0|CH1D1|CH1D0|CRC|
39
 
40
STATUS = Jennic Network Status (0 = OK, 1 = Coordinator not available, 2 = General Error)
41
CHN = Channel Pair (0 = Channel 0 & 1 ...etc)
42
 
43
Channel Pair: |CHN|CHnD1|CHnD0|CHnD1|CHnD0|CRC|
44
CHN is the lower Channel index of the Channel Pair
45
n is the Channel
46
D1D0 is servo value as u16 in range of 7373 (1ms) to 14745 (2ms)
47
there are 8 channels submitted, i.e 4 servo pairs
48
 
49
Frame example with signal received:
50
FFFF 00 0036012B1E7f
51
FFFF 00 022AFB2AECC2
52
FFFF 00 042B4D2B4414
53
FFFF 00 0636872B33DE
54
 
55
Frame example with no signal received:
56
FFFF 01 (Network Coordinator not Accessible)
57
or
58
FFFF 02 (General Error)
59
***********************************************************************************************************/
60
 
61
#include <stdlib.h>
62
#include "jennic.h"
63
#include "rc.h"
64
#include "uart0.h"
65
 
66
uint8_t jen_status = 0;
67
uint8_t PacketBuffer[9];
68
 
69
typedef union
70
{
71
    int16_t Servo[2];
72
    uint8_t  byte[4];
73
} ChannelPair_t;
74
 
75
ChannelPair_t ChannelPair;
76
 
77
// to be called within the UART RX ISR
78
void jen_parser (uint8_t c)
79
{
80
          static uint8_t last_c = 0;
81
    static uint8_t crc  = 0;
82
    static uint8_t cnt = 0;
83
    uint8_t packet_len = 5;
84
 
85
    // sync condition
86
    if ((c==0xFF) && (last_c==0xFF))
87
    {
88
        cnt = 0; // reset counter
89
        crc = 0; // reset checksum
90
        return;
91
    }
92
 
93
    if (cnt > packet_len) // packet complete, crc received
94
    {
95
        // calculate checksum
96
        crc = ~crc;
97
        if (crc == 0xFF) crc = 0xFE;
98
        // decode packet if checksum correct
99
        if (c == crc) jen_decode_packet ();
100
 
101
        // handle next packet
102
        cnt = 0;
103
        crc = 0;
104
    }
105
 
106
    else // collect channel data bytes
107
    {
108
        PacketBuffer[cnt++] = c;
109
        crc += c;
110
    }
111
 
112
    last_c = c; // store last byte for sync check
113
}
114
 
115
void jen_decode_packet (void)
116
{
117
    uint8_t  i;
118
 
119
    jen_status = PacketBuffer[0];
120
 
121
    // header condition
122
    if (!(PacketBuffer[1] & 0xF0))
123
    {
124
        if (!jen_status) RC_Quality = 200;
125
        else if (jen_status)
126
        {
127
            RC_Quality = 0;
128
            for (i = 0; i<5; i++)
129
            {
130
                PPM_diff[i] = 0;
131
                PPM_in[i] = 0;
132
            }
133
        }
134
 
135
        i = PacketBuffer[1] & 0x0F;   // lower nibble header indicates the channel pair
136
        if (i < 10) // maximum 12 channels
137
        {
138
            // big to little endian
139
            ChannelPair.byte[1] = PacketBuffer[2];
140
            ChannelPair.byte[0] = PacketBuffer[3];
141
            ChannelPair.byte[3] = PacketBuffer[4];
142
            ChannelPair.byte[2] = PacketBuffer[5];
143
 
144
            // new servo signal properly received
145
            jen_new_signal (i,  ChannelPair.Servo[0]);
146
            jen_new_signal (i+1, ChannelPair.Servo[1]);
147
        }
148
    } // end of header condition
149
}
150
 
151
// Parameters: channel  - channel number (0-9)
152
//             signal     - signal between 7363 and 14875
153
void jen_new_signal (uint8_t channel, int16_t signal)
154
{
155
    int16_t tmp;
156
    uint8_t index = channel + 1; // mk channels start with 1
157
 
158
    signal-= 11059;     // shift to neutral
159
    signal/= 24;        // scale to mk rc resolution
160
 
161
    // calculate exponential history for signal
162
    tmp = (3 * (PPM_in[index]) + signal) / 4;
163
 
164
    if (tmp > signal+1) tmp--;
165
    else if (tmp < signal-1) tmp++;
166
 
167
    if (RC_Quality == 200)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for noise reduction
168
    else PPM_diff[index] = 0;
169
 
170
    PPM_in[index] = tmp; // update channel value
171
 
172
          if(index < 5) DebugOut.Analog[(20+index)] = PPM_in[index]; // debug output is handy whilst developing
173
 
174
    if (index == 4) NewPpmData = 0;
175
}