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 | } |