Subversion Repositories FlightCtrl

Rev

Rev 1199 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1199 killagreg 1
#include "dsl.h"
1200 killagreg 2
#include "rc.h"
1199 killagreg 3
 
4
/*
5
1. GND (at channel 4 side)
6
2. TxD
7
3. RxD
8
4. 5V
9
*/
10
 
11
// dsl protocol parser state machine
1200 killagreg 12
#define DSLSTATE_SYNC1  0
13
#define DSLSTATE_SYNC2  1
1199 killagreg 14
#define DSLSTATE_HDR    2
15
#define DSLSTATE_DATA   3
1200 killagreg 16
#define DSLSTATE_CRC    4
1199 killagreg 17
 
18
#define DSL_SYNC1_CHAR 0xFF
19
#define DSL_SYNC2_CHAR 0xFF
20
 
21
 
1200 killagreg 22
uint8_t dsl_RSSI = 0;
23
uint8_t dsl_Battery = 0;
24
uint8_t dsl_Allocation = 0;
25
uint8_t PacketBuffer[6];
1199 killagreg 26
 
1200 killagreg 27
typedef union
28
{
29
        int16_t Servo[2];
30
        uint8_t  byte[4];
31
} ServoPair_t;
1199 killagreg 32
 
1200 killagreg 33
ServoPair_t ServoPair;
1199 killagreg 34
 
1200 killagreg 35
 
1199 killagreg 36
// This function is called, when a new servo signal is properly received.
37
// Parameters: servo  - servo number (0-9)
38
//             signal - servo signal between 7373 (1ms) and 14745 (2ms)
39
void dsl_new_signal(uint8_t channel, int16_t signal)
40
{
1200 killagreg 41
    int16_t tmp;
42
    uint8_t index = channel + 1; // mk channels start with 1
1199 killagreg 43
 
44
 
45
    // Signal vom  ACTDSL-Empfänger liegt zwischen
46
    // 7373 (1ms) und 14745 (2ms).
1200 killagreg 47
    signal-= 11059;     // shift to neutral
48
    signal/= 24;        // scale to mk rc resolution
1199 killagreg 49
 
1200 killagreg 50
        // calculate exponential history for signal
51
        tmp = (3 * (PPM_in[index]) + signal) / 4;
52
        if(tmp > signal+1) tmp--; else
53
        if(tmp < signal-1) tmp++;
54
        // calculate signal difference on good signal level
55
        if(RC_Quality >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for noise reduction
56
        else PPM_diff[index] = 0;
57
        PPM_in[index] = tmp; // update channel value
1199 killagreg 58
 
1200 killagreg 59
    if(index == 4) NewPpmData = 0;
1199 killagreg 60
}
61
 
62
// This function is called within dsl_parser(), when a complete
63
// data packet with valid checksum has been received.
1200 killagreg 64
void dsl_decode_packet(void)
1199 killagreg 65
{
66
    uint8_t  i;
67
 
1200 killagreg 68
    if(PacketBuffer[0] == 0x1F) // separate status frame
69
    {
70
        dsl_Allocation  = PacketBuffer[1]; // Get frequency allocation
71
        // ??                   = PacketBuffer[2];
72
        dsl_RSSI                = PacketBuffer[3]; // Get signal quality
73
        RC_Quality              = dsl_RSSI; // have to be scaled
74
        dsl_Battery     = PacketBuffer[4]; // Get voltage of battery supply
75
        // ??                   = PacketBuffer[5];
76
        }
77
    else // analyze servo pair frame
78
    {
79
                i = PacketBuffer[0] & 0x0F;   // last 4 bits of the header indicates servo pair
80
                if(i < 10)
81
                {
82
                        // big to little endian
83
                        ServoPair.byte[1] = PacketBuffer[1];
84
                        ServoPair.byte[0] = PacketBuffer[2];
85
                        ServoPair.byte[3] = PacketBuffer[3];
86
            ServoPair.byte[2] = PacketBuffer[4];
87
                        dsl_new_signal(i,  ServoPair.Servo[0]);
88
                        dsl_new_signal(i+1,ServoPair.Servo[0]);
89
                }
90
        }
1199 killagreg 91
}
92
 
93
 
1200 killagreg 94
// Status Frame: |0xFF|0xFF|0x1F|FREQALLOC|??|RSSI|VBAT|??|CRC|
1199 killagreg 95
// FREQ ALLOC = 35, 40, 72
96
// RSSI = 0.. 255                               // Received signal strength indicator
97
// VBAT = 0...255                               // supply voltage (0.0V.. 8.2V)
98
//
1200 killagreg 99
// Servo Pair:   |0xFF|0xFF|0x1X|D0|D1|D2|D3|CRC|
100
// X is channel index of 1 servo value
101
// D0, D1 is servo channel X
102
// D2, D3 is servo channel X+1
1199 killagreg 103
 
104
// this function should be called within the UART RX ISR
105
void dsl_parser(uint8_t c)
106
{
107
        static uint8_t crc      = 0;
1200 killagreg 108
        static uint8_t cnt = 0;
109
        static uint8_t packet_len = 0;
1199 killagreg 110
 
1200 killagreg 111
        static uint8_t dslstate = DSLSTATE_SYNC1;
1199 killagreg 112
 
113
        switch(dslstate)
114
        {
1200 killagreg 115
                case DSLSTATE_SYNC1: // check 1st sync byte
116
                        if (c == DSL_SYNC1_CHAR) dslstate = DSLSTATE_SYNC2;
117
                        else dslstate = DSLSTATE_SYNC1; // out of synchronization
1199 killagreg 118
                        break;
119
 
1200 killagreg 120
                case DSLSTATE_SYNC2: // check 2nd sync byte
121
                        if (c == DSL_SYNC2_CHAR) dslstate = DSLSTATE_HDR; // snchrinization complete trigger to cmd
122
                        else dslstate = DSLSTATE_SYNC1; // out of synchronization
1199 killagreg 123
                        break;
124
 
1200 killagreg 125
                case DSLSTATE_HDR: // check header byte
126
                        if ((c & 0xF0) != 0x10)
127
                        {
128
                                dslstate = DSLSTATE_SYNC1;
129
                        }
130
                        else
131
                        {
132
                                cnt = 0;
133
                                PacketBuffer[cnt++] = c;
134
                                crc = c;
135
                                if(c == 0x1F)  packet_len = 5;
136
                                else           packet_len = 4;
137
                                dslstate = DSLSTATE_DATA;
138
                        }
1199 killagreg 139
                        break;
140
 
141
                case DSLSTATE_DATA:
1200 killagreg 142
                        PacketBuffer[cnt++] = c;
1199 killagreg 143
                        crc += c;
1200 killagreg 144
                        if(cnt > packet_len) dslstate = DSLSTATE_CRC;
1199 killagreg 145
                        break;
146
 
147
                case DSLSTATE_CRC:
148
                        // Calculate checksum
149
                        crc = ~crc;
150
                        if (crc == 0xFF) crc = 0xFE;
1200 killagreg 151
                        // if crc matches
152
                if (c == crc) dsl_decode_packet();
153
                dslstate = DSLSTATE_SYNC1;
1199 killagreg 154
                        break;
155
 
156
                default: // unknown ubx state
1200 killagreg 157
                        dslstate = DSLSTATE_SYNC1;
1199 killagreg 158
                        break;
159
        }
1200 killagreg 160
}