Paparazzi UAS  v6.0_unstable-94-gda5b527-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
cc2500_frsky_x.c
Go to the documentation of this file.
1 #include "cc2500_compat.h"
2 
3 #include "peripherals/cc2500.h"
4 #include "cc2500_settings.h"
5 #include "cc2500_rx_spi_common.h"
6 #include "cc2500_common.h"
7 #include "cc2500_frsky_common.h"
8 #include "cc2500_frsky_shared.h"
9 #include "cc2500_frsky_x.h"
10 #include "cc2500_smartport.h"
11 
12 #define UNUSED(x) (void)(x)
13 
14 // betaflight/src/main/rx/cc2500_frsky_x.c @ e78f976
15 /*
16  * This file is part of Cleanflight and Betaflight.
17  *
18  * Cleanflight and Betaflight are free software. You can redistribute
19  * this software and/or modify this software under the terms of the
20  * GNU General Public License as published by the Free Software
21  * Foundation, either version 3 of the License, or (at your option)
22  * any later version.
23  *
24  * Cleanflight and Betaflight are distributed in the hope that they
25  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27  * See the GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this software.
31  *
32  * If not, see <http://www.gnu.org/licenses/>.
33  */
34 
35 #include <string.h>
36 
37 //#include "platform.h"
38 
39 #ifdef USE_RX_FRSKY_SPI_X
40 
41 //#include "build/build_config.h"
42 //#include "build/debug.h"
43 //
44 //#include "common/maths.h"
45 //#include "common/utils.h"
46 //
47 //#include "config/feature.h"
48 //
49 //#include "drivers/adc.h"
50 //#include "drivers/rx/rx_cc2500.h"
51 //#include "drivers/io.h"
52 //#include "drivers/io_def.h"
53 //#include "drivers/io_types.h"
54 //#include "drivers/resource.h"
55 //#include "drivers/system.h"
56 //#include "drivers/time.h"
57 //
58 //#include "fc/config.h"
59 //
60 //#include "pg/rx.h"
61 //#include "pg/rx_spi.h"
62 //#include "pg/rx_spi_cc2500.h"
63 //
64 //#include "rx/rx_spi_common.h"
65 //#include "rx/cc2500_common.h"
66 //#include "rx/cc2500_frsky_common.h"
67 //#include "rx/cc2500_frsky_shared.h"
68 //
69 //#include "sensors/battery.h"
70 //
71 //#include "telemetry/smartport.h"
72 //
73 //#include "cc2500_frsky_x.h"
74 
75 const uint16_t crcTable[] = {
76  0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
77  0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
78  0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
79  0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
80  0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
81  0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
82  0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
83  0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
84  0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
85  0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
86  0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
87  0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
88  0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
89  0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
90  0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
91  0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
92  0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
93  0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
94  0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
95  0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
96  0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
97  0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
98  0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
99  0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
100  0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
101  0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
102  0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
103  0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
104  0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
105  0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
106  0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
107  0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
108 };
109 
110 #define TELEMETRY_OUT_BUFFER_SIZE 64
111 
112 #define TELEMETRY_SEQUENCE_LENGTH 4
113 
114 #define A1_CONST_X 50
115 
117  unsigned int packetSequenceId: 2;
118  unsigned int unused: 1;
119  unsigned int initRequest: 1;
120  unsigned int ackSequenceId: 2;
121  unsigned int retransmissionRequested: 1;
122  unsigned int initResponse: 1;
123 } __attribute__ ((__packed__)) telemetrySequenceMarkerData_t;
124 
127  telemetrySequenceMarkerData_t data;
128 } __attribute__ ((__packed__)) telemetrySequenceMarker_t;
129 
130 #define SEQUENCE_MARKER_REMOTE_PART 0xf0
131 
132 #define TELEMETRY_DATA_SIZE 5
133 
134 typedef struct telemetryData_s {
137 } __attribute__ ((__packed__)) telemetryData_t;
138 
139 typedef struct telemetryBuffer_s {
140  telemetryData_t data;
143 
144 #define TELEMETRY_FRAME_SIZE sizeof(telemetryData_t)
145 
146 typedef struct telemetryPayload_s {
149  telemetrySequenceMarker_t sequence;
152 } __attribute__ ((__packed__)) telemetryPayload_t;
153 
154 #if defined(USE_RX_FRSKY_SPI_TELEMETRY)
156 #endif
157 
159 
160 static telemetrySequenceMarker_t responseToSend;
161 
162 #if defined(USE_RX_FRSKY_SPI_TELEMETRY)
163 static uint8_t frame[20];
164 
165 #if defined(USE_TELEMETRY_SMARTPORT)
167 
169 
170 static bool telemetryEnabled = false;
171 
174 #endif
175 #endif // USE_RX_FRSKY_SPI_TELEMETRY
176 
179 
180 static uint16_t calculateCrc(const uint8_t *data, uint8_t len) {
181  uint16_t crc = 0;
182  for (unsigned i = 0; i < len; i++) {
183  crc = (crc << 8) ^ (crcTable[((uint8_t)(crc >> 8) ^ *data++) & 0xFF]);
184  }
185  return crc;
186 }
187 
188 #if defined(USE_RX_FRSKY_SPI_TELEMETRY)
189 #if defined(USE_TELEMETRY_SMARTPORT)
191 {
192  static uint8_t telemetryOutReader = 0;
193 
194  uint8_t index;
195  for (index = 0; index < TELEMETRY_DATA_SIZE; index++) { // max 5 bytes in a frame
196  if (telemetryOutReader == telemetryOutWriter){ // no new data
197  break;
198  }
199  buf[index] = telemetryOutBuffer[telemetryOutReader];
200  telemetryOutReader = (telemetryOutReader + 1) % TELEMETRY_OUT_BUFFER_SIZE;
201  }
202 
203  return index;
204 }
205 #endif
206 
207 static void buildTelemetryFrame(uint8_t *packet)
208 {
209  static uint8_t localPacketId;
210 
211  static bool evenRun = false;
212 
213  frame[0] = 0x0E;//length
214  frame[1] = rxCc2500SpiConfig()->bindTxId[0];
215  frame[2] = rxCc2500SpiConfig()->bindTxId[1];
216  frame[3] = packet[3];
217 
218  if (evenRun) {
219  frame[4] = (uint8_t)cc2500getRssiDbm() | 0x80;
220  } else {
221  uint8_t a1Value;
222  switch (rxCc2500SpiConfig()->a1Source) {
224  a1Value = getLegacyBatteryVoltage() & 0x7f;
225  break;
227  a1Value = (uint8_t)((adcGetChannel(ADC_EXTERNAL1) & 0xfe0) >> 5);
228  break;
230  a1Value = A1_CONST_X & 0x7f;
231  break;
232  }
233  frame[4] = a1Value;
234  }
235  evenRun = !evenRun;
236 
237  telemetrySequenceMarker_t *inFrameMarker = (telemetrySequenceMarker_t *)&packet[21];
238  telemetrySequenceMarker_t *outFrameMarker = (telemetrySequenceMarker_t *)&frame[5];
239  if (inFrameMarker->data.initRequest) { // check syncronization at startup ok if not no sport telemetry
240  outFrameMarker-> raw = 0;
241  outFrameMarker->data.initRequest = 1;
242  outFrameMarker->data.initResponse = 1;
243 
244  localPacketId = 0;
245  } else {
246  if (inFrameMarker->data.retransmissionRequested) {
247  uint8_t retransmissionFrameId = inFrameMarker->data.ackSequenceId;
248  outFrameMarker->raw = responseToSend.raw & SEQUENCE_MARKER_REMOTE_PART;
249  outFrameMarker->data.packetSequenceId = retransmissionFrameId;
250 
251  memcpy(&frame[6], &telemetryTxBuffer[retransmissionFrameId], TELEMETRY_FRAME_SIZE);
252  } else {
253  uint8_t localAckId = inFrameMarker->data.ackSequenceId;
254  if (localPacketId != (localAckId + 1) % TELEMETRY_SEQUENCE_LENGTH) {
255  outFrameMarker->raw = responseToSend.raw & SEQUENCE_MARKER_REMOTE_PART;
256  outFrameMarker->data.packetSequenceId = localPacketId;
257 
258  frame[6] = appendSmartPortData(&frame[7]);
259  memcpy(&telemetryTxBuffer[localPacketId], &frame[6], TELEMETRY_FRAME_SIZE);
260 
261  localPacketId = (localPacketId + 1) % TELEMETRY_SEQUENCE_LENGTH;
262  }
263  }
264  }
265 
266  uint16_t lcrc = calculateCrc(&frame[3], 10);
267  frame[13]=lcrc>>8;
268  frame[14]=lcrc;
269 }
270 
271 static bool frSkyXCheckQueueEmpty(void)
272 {
273  return true;
274 }
275 
276 #if defined(USE_TELEMETRY_SMARTPORT)
278  if (c == FSSP_DLE || c == FSSP_START_STOP) {
279  telemetryOutBuffer[telemetryOutWriter] = FSSP_DLE;
280  telemetryOutWriter = (telemetryOutWriter + 1) % TELEMETRY_OUT_BUFFER_SIZE;
281  telemetryOutBuffer[telemetryOutWriter] = c ^ FSSP_DLE_XOR;
282  telemetryOutWriter = (telemetryOutWriter + 1) % TELEMETRY_OUT_BUFFER_SIZE;
283  } else {
284  telemetryOutBuffer[telemetryOutWriter] = c;
285  telemetryOutWriter = (telemetryOutWriter + 1) % TELEMETRY_OUT_BUFFER_SIZE;
286  }
287 }
288 
290 {
291  telemetryOutBuffer[telemetryOutWriter] = FSSP_START_STOP;
292  telemetryOutWriter = (telemetryOutWriter + 1) % TELEMETRY_OUT_BUFFER_SIZE;
293  telemetryOutBuffer[telemetryOutWriter] = FSSP_SENSOR_ID1 & 0x1f;
294  telemetryOutWriter = (telemetryOutWriter + 1) % TELEMETRY_OUT_BUFFER_SIZE;
295  uint8_t *data = (uint8_t *)payload;
296  for (unsigned i = 0; i < sizeof(smartPortPayload_t); i++) {
297  frSkyXTelemetrySendByte(*data++);
298  }
299 }
300 #endif
301 #endif // USE_RX_FRSKY_SPI_TELEMETRY
302 
303 
304 void frSkyXSetRcData(uint16_t *rcData, const uint8_t *packet)
305 {
306  uint16_t c[8];
307  // ignore failsafe packet
308  if (packet[7] != 0) {
309  return;
310  }
311  c[0] = (uint16_t)((packet[10] << 8) & 0xF00) | packet[9];
312  c[1] = (uint16_t)((packet[11] << 4) & 0xFF0) | (packet[10] >> 4);
313  c[2] = (uint16_t)((packet[13] << 8) & 0xF00) | packet[12];
314  c[3] = (uint16_t)((packet[14] << 4) & 0xFF0) | (packet[13] >> 4);
315  c[4] = (uint16_t)((packet[16] << 8) & 0xF00) | packet[15];
316  c[5] = (uint16_t)((packet[17] << 4) & 0xFF0) | (packet[16] >> 4);
317  c[6] = (uint16_t)((packet[19] << 8) & 0xF00) | packet[18];
318  c[7] = (uint16_t)((packet[20] << 4) & 0xFF0) | (packet[19] >> 4);
319 
320  for (unsigned i = 0; i < 8; i++) {
321  const bool channelIsShifted = c[i] & 0x800;
322  const uint16_t channelValue = c[i] & 0x7FF;
323  rcData[channelIsShifted ? i + 8 : i] = ((channelValue - 64) * 2 + 860 * 3) / 3;
324  }
325 }
326 
327 bool isValidPacket(const uint8_t *packet)
328 {
329  uint16_t lcrc = calculateCrc(&packet[3], (packetLength - 7));
330  if ((lcrc >> 8) == packet[packetLength - 4] && (lcrc & 0x00FF) == packet[packetLength - 3] &&
331  (packet[0] == packetLength - 3) &&
332  (packet[1] == rxCc2500SpiConfig()->bindTxId[0]) &&
333  (packet[2] == rxCc2500SpiConfig()->bindTxId[1]) &&
334  (rxCc2500SpiConfig()->rxNum == 0 || packet[6] == 0 || packet[6] == rxCc2500SpiConfig()->rxNum)) {
335  return true;
336  }
337  return false;
338 }
339 
341 {
342  static unsigned receiveTelemetryRetryCount = 0;
343  static bool skipChannels = true;
344 
345  static uint8_t remoteAckId = 0;
346 
347  static timeUs_t packetTimerUs;
348 
349  static bool frameReceived;
350  static timeDelta_t receiveDelayUs;
351  static uint8_t channelsToSkip = 1;
352  static uint32_t packetErrors = 0;
353 
354 #if defined(USE_RX_FRSKY_SPI_TELEMETRY)
355  static bool telemetryReceived = false;
356 #endif
357 
359 
360  switch (*protocolState) {
361  case STATE_STARTING:
362  listLength = 47;
363  initialiseData(false);
364  *protocolState = STATE_UPDATE;
365  nextChannel(1);
367  break;
368  case STATE_UPDATE:
369  packetTimerUs = micros();
370  *protocolState = STATE_DATA;
371  frameReceived = false; // again set for receive
372  receiveDelayUs = 5300;
373  if (rxSpiCheckBindRequested(false)) {
374  packetTimerUs = 0;
375  timeoutUs = 50;
376  missingPackets = 0;
377  *protocolState = STATE_INIT;
378 
379  break;
380  }
381 
382  FALLTHROUGH;
383  // here FS code could be
384  case STATE_DATA:
385  if (cc2500getGdo() && (frameReceived == false)){
387  if (ccLen >= packetLength) {
388  cc2500ReadFifo(packet, packetLength);
389  if (isValidPacket(packet)) {
390  missingPackets = 0;
391  timeoutUs = 1;
392  receiveDelayUs = 0;
393  rxSpiLedOn();
394  if (skipChannels) {
395  channelsToSkip = packet[5] << 2;
396  if (packet[4] >= listLength) {
397  if (packet[4] < (64 + listLength)) {
398  channelsToSkip += 1;
399  } else if (packet[4] < (128 + listLength)) {
400  channelsToSkip += 2;
401  } else if (packet[4] < (192 + listLength)) {
402  channelsToSkip += 3;
403  }
404  }
405  telemetryReceived = true; // now telemetry can be sent
406  skipChannels = false;
407  }
408  cc2500setRssiDbm(packet[packetLength - 2]);
409 
410  telemetrySequenceMarker_t *inFrameMarker = (telemetrySequenceMarker_t *)&packet[21];
411 
412  uint8_t remoteNewPacketId = inFrameMarker->data.packetSequenceId;
413  memcpy(&telemetryRxBuffer[remoteNewPacketId].data, &packet[22], TELEMETRY_FRAME_SIZE);
414  telemetryRxBuffer[remoteNewPacketId].needsProcessing = true;
415 
416  responseToSend.raw = 0;
417  uint8_t remoteToAckId = (remoteAckId + 1) % TELEMETRY_SEQUENCE_LENGTH;
418  if (remoteNewPacketId != remoteToAckId) {
419  while (remoteToAckId != remoteNewPacketId) {
420  if (!telemetryRxBuffer[remoteToAckId].needsProcessing) {
421  responseToSend.data.ackSequenceId = remoteToAckId;
422  responseToSend.data.retransmissionRequested = 1;
423 
424  receiveTelemetryRetryCount++;
425 
426  break;
427  }
428 
429  remoteToAckId = (remoteToAckId + 1) % TELEMETRY_SEQUENCE_LENGTH;
430  }
431  }
432 
433  if (!responseToSend.data.retransmissionRequested) {
434  receiveTelemetryRetryCount = 0;
435 
436  remoteToAckId = (remoteAckId + 1) % TELEMETRY_SEQUENCE_LENGTH;
437  uint8_t remoteNextAckId = remoteToAckId;
438  while (telemetryRxBuffer[remoteToAckId].needsProcessing && remoteToAckId != remoteAckId) {
439  remoteNextAckId = remoteToAckId;
440  remoteToAckId = (remoteToAckId + 1) % TELEMETRY_SEQUENCE_LENGTH;
441  }
442  remoteAckId = remoteNextAckId;
443  responseToSend.data.ackSequenceId = remoteAckId;
444  }
445 
446  if (receiveTelemetryRetryCount >= 5) {
447 #if defined(USE_RX_FRSKY_SPI_TELEMETRY) && defined(USE_TELEMETRY_SMARTPORT)
448  remoteToProcessId = 0;
449  remoteToProcessIndex = 0;
450 #endif
451  remoteAckId = TELEMETRY_SEQUENCE_LENGTH - 1;
452  for (unsigned i = 0; i < TELEMETRY_SEQUENCE_LENGTH; i++) {
453  telemetryRxBuffer[i].needsProcessing = false;
454  }
455 
456  receiveTelemetryRetryCount = 0;
457  }
458 
459  packetTimerUs = micros();
460  frameReceived = true; // no need to process frame again.
461  }
462  if (!frameReceived) {
463  packetErrors++;
464  DEBUG_SET(DEBUG_RX_FRSKY_SPI, DEBUG_DATA_BAD_FRAME, packetErrors);
466  }
467  }
468  }
469  if (telemetryReceived) {
470  if (cmpTimeUs(micros(), packetTimerUs) > receiveDelayUs) { // if received or not received in this time sent telemetry data
471  *protocolState = STATE_TELEMETRY;
472  buildTelemetryFrame(packet);
473  }
474  }
475  if (cmpTimeUs(micros(), packetTimerUs) > timeoutUs * SYNC_DELAY_MAX) {
476  rxSpiLedToggle();
477 
479  nextChannel(1);
481  *protocolState = STATE_UPDATE;
482  }
483  if (frameReceived) {
484  ret |= RX_SPI_RECEIVED_DATA;
485  }
486 
487  break;
488 #ifdef USE_RX_FRSKY_SPI_TELEMETRY
489  case STATE_TELEMETRY:
490  if (cmpTimeUs(micros(), packetTimerUs) >= receiveDelayUs + telemetryDelayUs) { // if received or not received in this time sent telemetry data
492  cc2500SetPower(6);
494  delayMicroseconds(30);
495 #if defined(USE_RX_CC2500_SPI_PA_LNA)
496  cc2500TxEnable();
497 #endif
499  cc2500WriteFifo(frame, frame[0] + 1);
500 
501 #if defined(USE_TELEMETRY_SMARTPORT)
502  if (telemetryEnabled) {
504  }
505 #endif
506  *protocolState = STATE_RESUME;
507  }
508 
509  break;
510 #endif // USE_RX_FRSKY_SPI_TELEMETRY
511  case STATE_RESUME:
512  if (cmpTimeUs(micros(), packetTimerUs) > receiveDelayUs + 3700) {
513  packetTimerUs = micros();
514  receiveDelayUs = 5300;
515  frameReceived = false; // again set for receive
516  nextChannel(channelsToSkip);
518 #ifdef USE_RX_CC2500_SPI_PA_LNA
519  cc2500TxDisable();
520 #if defined(USE_RX_CC2500_SPI_DIVERSITY)
521  if (missingPackets >= 2) {
522  cc2500switchAntennae();
523  }
524 #endif
525 #endif // USE_RX_CC2500_SPI_PA_LNA
527  timeoutUs = 50;
528  skipChannels = true;
529  telemetryReceived = false;
530  *protocolState = STATE_UPDATE;
531  break;
532  }
533  missingPackets++;
535  *protocolState = STATE_DATA;
536  }
537  break;
538  }
539 
540  return ret;
541 }
542 
543 #if defined(USE_RX_FRSKY_SPI_TELEMETRY) && defined(USE_TELEMETRY_SMARTPORT)
545 {
546  static timeMs_t pollingTimeMs = 0;
547 
548  UNUSED(packet);
549 
550  bool clearToSend = false;
551  timeMs_t now = millis();
552  smartPortPayload_t *payload = NULL;
553  if ((now - pollingTimeMs) > 24) {
554  pollingTimeMs = now;
555 
556  clearToSend = true;
557  } else {
558  while (telemetryRxBuffer[remoteToProcessId].needsProcessing && !payload) {
559  if (remoteToProcessIndex >= telemetryRxBuffer[remoteToProcessId].data.dataLength) {
560  remoteToProcessIndex = 0;
561  telemetryRxBuffer[remoteToProcessId].needsProcessing = false;
562  remoteToProcessId = (remoteToProcessId + 1) % TELEMETRY_SEQUENCE_LENGTH;
563 
564  if (!telemetryRxBuffer[remoteToProcessId].needsProcessing) {
565  break;
566  }
567  }
568 
569  while (remoteToProcessIndex < telemetryRxBuffer[remoteToProcessId].data.dataLength && !payload) {
570  payload = smartPortDataReceive(telemetryRxBuffer[remoteToProcessId].data.data[remoteToProcessIndex], &clearToSend, frSkyXCheckQueueEmpty, false);
571  remoteToProcessIndex = remoteToProcessIndex + 1;
572  }
573  }
574  }
575 
576  processSmartPortTelemetry(payload, &clearToSend, NULL);
577 
578  return RX_SPI_RECEIVED_NONE;
579 }
580 #endif
581 
583 {
584  switch(spiProtocol) {
585  case RX_SPI_FRSKY_X:
586  packetLength = 32;
587  telemetryDelayUs = 400;
588  break;
589  case RX_SPI_FRSKY_X_LBT:
590  packetLength = 35;
591  telemetryDelayUs = 1400;
592  break;
593  default:
594  break;
595  }
596 #if defined(USE_TELEMETRY_SMARTPORT)
599  }
600 #endif
601 }
602 
603 #endif
static uint8_t protocolState
static uint16_t telemetryDelayUs
static void frSkyXTelemetrySendByte(uint8_t c)
static uint8_t appendSmartPortData(uint8_t *buf)
#define getLegacyBatteryVoltage()
#define FALLTHROUGH
Definition: cc2500_compat.h:86
smartPortPayload_t * smartPortDataReceive(uint16_t c, bool *clearToSend, smartPortCheckQueueEmptyFn *checkQueueEmpty, bool useChecksum)
static uint8_t frame[20]
void setRssiDirect(uint16_t newRssi, rssiSource_e source)
Definition: cc2500_rx.c:700
uint32_t timeUs_t
Definition: cc2500_compat.h:93
#define SEQUENCE_MARKER_REMOTE_PART
rx_spi_received_e frSkyXHandlePacket(uint8_t *const packet, uint8_t *const protocolState)
#define DEBUG_DATA_BAD_FRAME
#define MAX_MISSING_PKT
uint8_t cc2500ReadReg(uint8_t reg)
Definition: cc2500.c:199
int32_t timeDelta_t
Definition: cc2500_compat.h:91
void cc2500ReadFifo(uint8_t *dpbuffer, uint8_t len)
Definition: cc2500.c:174
struct telemetryBuffer_s telemetryBuffer_t
#define DEBUG_DATA_MISSING_PACKETS
#define featureIsEnabled(mask)
#define ADC_EXTERNAL1
#define TELEMETRY_OUT_BUFFER_SIZE
timeDelta_t timeoutUs
rx_spi_received_e
Definition: cc2500_rx_spi.h:54
void cc2500setRssiDbm(uint8_t value)
Definition: cc2500_common.c:69
telemetryData_t data
static uint8_t telemetryOutBuffer[TELEMETRY_OUT_BUFFER_SIZE]
rx_spi_protocol_e
Definition: cc2500_rx_spi.h:34
bool initSmartPortTelemetryExternal(smartPortWriteFrameFn *smartPortWriteFrameExternal)
#define TELEMETRY_FRAME_SIZE
uint32_t timeMs_t
Definition: cc2500_compat.h:92
#define CC2500_SRX
Definition: cc2500.h:148
static uint8_t remoteToProcessId
static bool frSkyXCheckQueueEmpty(void)
#define CC2500_SFRX
Definition: cc2500.h:161
int16_t rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]
Definition: cc2500_rx.c:118
uint8_t data[TELEMETRY_DATA_SIZE]
#define adcGetChannel(channel)
const uint16_t crcTable[]
#define UNUSED(x)
uint8_t listLength
#define delayMicroseconds(us)
Definition: cc2500.c:70
telemetrySequenceMarkerData_t data
void cc2500SetPower(uint8_t power)
Definition: cc2500.c:211
static uint16_t calculateCrc(const uint8_t *data, uint8_t len)
rx_spi_received_e frSkyXProcessFrame(uint8_t *const packet)
void processSmartPortTelemetry(smartPortPayload_t *payload, volatile bool *clearToSend, const timeUs_t *requestTimeout)
struct smartPortPayload_s smartPortPayload_t
bool isValidPacket(const uint8_t *packet)
static uint8_t packetLength
void frSkyXInit(const rx_spi_protocol_e spiProtocol)
#define TELEMETRY_DATA_SIZE
static rx_spi_protocol_e spiProtocol
void nextChannel(uint8_t skip)
#define DEBUG_SET(...)
Definition: cc2500_compat.h:62
const rxCc2500SpiConfig_t * rxCc2500SpiConfig(void)
void rxSpiLedOn(void)
#define millis()
static bool telemetryEnabled
static telemetryData_t telemetryTxBuffer[TELEMETRY_SEQUENCE_LENGTH]
#define micros()
static void frSkyXTelemetryWriteFrame(const smartPortPayload_t *payload)
#define CC2500_SIDLE
Definition: cc2500.h:155
void frSkyXSetRcData(uint16_t *rcData, const uint8_t *packet)
bool rxSpiCheckBindRequested(bool reset)
static telemetryBuffer_t telemetryRxBuffer[TELEMETRY_SEQUENCE_LENGTH]
static void buildTelemetryFrame(uint8_t *packet)
void initialiseData(bool inBindState)
static timeDelta_t cmpTimeUs(timeUs_t a, timeUs_t b)
Definition: cc2500_compat.h:96
#define SYNC_DELAY_MAX
#define TELEMETRY_SEQUENCE_LENGTH
static telemetrySequenceMarker_t responseToSend
void cc2500WriteFifo(uint8_t *dpbuffer, uint8_t len)
Definition: cc2500.c:180
telemetrySequenceMarker_t sequence
#define CC2500_READ_BURST
Definition: cc2500.h:137
uint32_t missingPackets
uint16_t cc2500getRssiDbm(void)
Definition: cc2500_common.c:64
static uint8_t telemetryOutWriter
bool cc2500getGdo(void)
Definition: cc2500_common.c:80
#define A1_CONST_X
static uint8_t remoteToProcessIndex
telemetryData_t data
void rxSpiLedToggle(void)
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
void cc2500Strobe(uint8_t address)
Definition: cc2500.c:204
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78