2 #ifndef OXS_OUT_FRSKY_h
3 #define OXS_OUT_FRSKY_h
5 #include "oXs_config_basic.h"
6 #include "oXs_config_advanced.h"
7 #include "oXs_config_macros.h"
8 #include "oXs_ms5611.h" // we need the variodata struct
9 #include "oXs_4525.h" // we need the airspeeddata struct
10 #include "oXs_curr.h" // we need the currentdata struct
11 #include "oXs_voltage.h" // we need the arduinodata struct
12 #include "oXs_ads1115.h" // we need the data
13 #include "oXs_sdp3x.h" // we need the airspeed data
14 //#include <Arduino.h>
15 #include "oXs_general.h"
16 // this file is used only for FRSKY
17 #if defined(PROTOCOL) && ( (PROTOCOL == FRSKY_SPORT) || ( PROTOCOL == FRSKY_HUB ) || (PROTOCOL == FRSKY_SPORT_HUB ) ) //if Frsky protocol is used
19 //#define DEBUG_SETUP_PIN 5 // allows to send a pulse on an output pin during the enlapsed time that Arduino runs the set up
20 //#define DEBUG_SPORT_PIN 6 // allows to send a pulse on an output pin during the enlapsed time that Arduino checks for SPORT
22 #define INTERVAL_FRAME1 200
23 #define INTERVAL_FRAME2 1000 // used by GPS
25 // default SPORT_SENSOR_ID
26 //#define DATA_ID_VARIO 0x00 // = sensor 0 used for Alt and Vspeed
27 //#define DATA_ID_FLVSS 0xA1 // 1
28 //#define DATA_ID_FAS 0x22 // 2
29 //#define DATA_ID_GPS 0x83 // 3 used for all GPS data
30 //#define DATA_ID_RPM 0xE4 // 4
31 //#define DATA_ID_ACC 0x67 // 7
32 //list of 28 device ID codes is (in sequence)
33 // 0x00,0xA1,0x22,0x83,0xE4,0x45,0xC6,0x67,0x48,0xE9,0x6A,0xCB,0xAC,0x0D,0x8E,0x2F,0xD0,0x71,0xF2,0x53,0x34,0x95,0x16,0xB7,0x98,0x39,0xBA,0x1B
36 // FrSky new DATA IDs (2 bytes) (copied from openTX telemetry/frsky_sport.cpp on 11 jul 2014) // those values are not used directly but bits 4 up to 11 are stored in an array in oXs_out_frsky.cpp
37 #define ALT_FIRST_ID 0x0100
38 #define ALT_LAST_ID 0x010f
39 #define VARIO_FIRST_ID 0x0110
40 #define VARIO_LAST_ID 0x011f
41 #define CURR_FIRST_ID 0x0200
42 #define CURR_LAST_ID 0x020f
43 #define VFAS_FIRST_ID 0x0210
44 #define VFAS_LAST_ID 0x021f
45 #define CELLS_FIRST_ID 0x0300
46 #define CELLS_SECOND_ID 0x0301
47 #define CELLS_THIRD_ID 0x0302
48 #define CELLS_LAST_ID 0x030f
49 #define T1_FIRST_ID 0x0400
50 #define T1_LAST_ID 0x040f
51 #define T2_FIRST_ID 0x0410
52 #define T2_LAST_ID 0x041f
53 #define RPM_FIRST_ID 0x0500
54 #define RPM_LAST_ID 0x050f
55 #define FUEL_FIRST_ID 0x0600
56 #define FUEL_LAST_ID 0x060f
57 #define ACCX_FIRST_ID 0x0700
58 #define ACCX_LAST_ID 0x070f
59 #define ACCY_FIRST_ID 0x0710
60 #define ACCY_LAST_ID 0x071f
61 #define ACCZ_FIRST_ID 0x0720
62 #define ACCZ_LAST_ID 0x072f
63 #define GPS_LONG_LATI_FIRST_ID 0x0800
64 #define GPS_LONG_LATI_LAST_ID 0x080f
65 #define GPS_ALT_FIRST_ID 0x0820
66 #define GPS_ALT_LAST_ID 0x082f
67 #define GPS_SPEED_FIRST_ID 0x0830
68 #define GPS_SPEED_LAST_ID 0x083f
69 #define GPS_COURS_FIRST_ID 0x0840
70 #define GPS_COURS_LAST_ID 0x084f
71 #define GPS_TIME_DATE_FIRST_ID 0x0850
72 #define GPS_TIME_DATE_LAST_ID 0x085f
73 #define A3_FIRST_ID 0x0900
74 #define A3_LAST_ID 0x090f
75 #define A4_FIRST_ID 0x0910
76 #define A4_LAST_ID 0x091f
77 #define AIR_SPEED_FIRST_ID 0x0a00
78 #define AIR_SPEED_LAST_ID 0x0a0f
79 #define RSSI_ID 0xf101 // please do not use this code because it is already used by the receiver
80 #define ADC1_ID 0xf102 // please do not use this code because it is already used by the receiver
81 #define ADC2_ID 0xf103
82 #define BATT_ID 0xf104
83 #define SWR_ID 0xf105 // please do not use this code because it is already used by the receiver
84 // End of list of all telemetry fields supported by SPORT (defined by Frsky)
86 //list of all telemetry fields supported by Hub protocol (defined by Frsky)
87 #define FRSKY_USERDATA_GPS_ALT_B 0x01
88 #define FRSKY_USERDATA_TEMP1 0x02
89 #define FRSKY_USERDATA_RPM 0x03
90 #define FRSKY_USERDATA_FUEL 0x04
91 #define FRSKY_USERDATA_TEMP2 0x05
92 #define FRSKY_USERDATA_CELL_VOLT 0x06
93 #define FRSKY_USERDATA_GPS_ALT_A 0x09
94 #define FRSKY_USERDATA_BARO_ALT_B 0x10
95 #define FRSKY_USERDATA_GPS_SPEED_B 0x11
96 #define FRSKY_USERDATA_GPS_LONG_B 0x12
97 #define FRSKY_USERDATA_GPS_LAT_B 0x13
98 #define FRSKY_USERDATA_GPS_CURSE_B 0x14
99 #define FRSKY_USERDATA_GPS_DM 0x15
100 #define FRSKY_USERDATA_GPS_YEAR 0x16
101 #define FRSKY_USERDATA_GPS_HM 0x17
102 #define FRSKY_USERDATA_GPS_SEC 0x18
103 #define FRSKY_USERDATA_GPS_SPEED_A 0x19
104 #define FRSKY_USERDATA_GPS_LONG_A 0x1A
105 #define FRSKY_USERDATA_GPS_LAT_A 0x1B
106 #define FRSKY_USERDATA_GPS_CURSE_A 0x1C
107 #define FRSKY_USERDATA_BARO_ALT_A 0x21
108 #define FRSKY_USERDATA_GPS_LONG_EW 0x22
109 #define FRSKY_USERDATA_GPS_LAT_EW 0x23
110 #define FRSKY_USERDATA_ACC_X 0x24
111 #define FRSKY_USERDATA_ACC_Y 0x25
112 #define FRSKY_USERDATA_ACC_Z 0x26
113 #define FRSKY_USERDATA_CURRENT 0x28
114 #define FRSKY_USERDATA_VERT_SPEED 0x30 // open9x Vario Mode Only
115 #define FRSKY_USERDATA_ALT_MIN 0x31 // open9x Vario Mode Only
116 #define FRSKY_USERDATA_ALT_MAX 0x32 // open9x Vario Mode Only
117 #define FRSKY_USERDATA_RPM_MAX 0x33 // open9x Vario Mode Only
118 #define FRSKY_USERDATA_T1_MAX 0x34 // open9x Vario Mode Only
119 #define FRSKY_USERDATA_T2_MAX 0x35 // open9x Vario Mode Only
120 #define FRSKY_USERDATA_GPS_SPEED_MAX 0x36 // open9x Vario Mode Only
121 #define FRSKY_USERDATA_GPS_DIS_MAX 0x37 // open9x Vario Mode Only
122 #define FRSKY_USERDATA_VFAS_NEW 0x39 // Use this field in order to display the value on VFAS on Tx, Take care that for a voltage, the value must be in 1/10 of Volt and not in mVolt
123 #define FRSKY_USERDATA_VOLTAGE_B 0x3A // do not use this code to transmit a voltage. It requires a special formatting that is not implemented. Use VFAS_NEW instead
124 #define FRSKY_USERDATA_VOLTAGE_A 0x3B // do not use this code to transmit a voltage. It requires a special formatting that is not implemented. Use VFAS_NEW instead
125 #define FRSKY_USERDATA_GPS_DIST 0x3C
126 #define FRSKY_USERDATA_FUELPERCENT 0x3D
127 // Endof list of all telemetry fields supported by Hub protocol (defined by Frsky)
131 // mapping of fields to send
132 #define DEFAULTFIELD 0x00 // value to let OXS select automatically the best telemetry field.
149 // This is the list of codes for each available measurements
151 #define VERTICAL_SPEED 2
152 #define SENSITIVITY 3
153 #define ALT_OVER_10_SEC 4
166 #define ALTIMETER_2 17
167 #define VERTICAL_SPEED_2 18
168 #define SENSITIVITY_2 19
169 #define ALT_OVER_10_SEC_2 20
171 #define PRANDTL_COMPENSATION 22
172 #define PPM_VSPEED 23
174 #define PRANDTL_DTE 25
178 #define VERTICAL_SPEED_A 29
179 #define VERTICAL_SPEED_I 30
180 #define GLIDER_RATIO 31
181 #define SECONDS_SINCE_T0 32
182 #define AVERAGE_VSPEED_SINCE_TO 33
191 // to do : add alt min, alt max , rpm max? , current max (not sure that it is neaded because it can be calculated on TX side
192 // End of list of type of available measurements
196 #define UNKNOWN false
199 /***************************************************************************************/
200 /* Transmission status */
201 /***************************************************************************************/
212 OXS_OUT(uint8_t pinTx
,HardwareSerial
&print
);
214 OXS_OUT(uint8_t pinTx
);
216 VARIODATA
* varioData
;
217 VARIODATA
* varioData_2
;
218 AIRSPEEDDATA
* airSpeedData
;
219 CURRENTDATA
* currentData
;
220 VOLTAGEDATA
* voltageData
;
221 // uint8_t currentValueType ; //e.g. = ALTIMETER, VERTICAL_SPEED, = field_Id to transmit
226 // used by both protocols
229 HardwareSerial
* printer
;
232 #if defined( PROTOCOL ) && ( ( PROTOCOL == FRSKY_SPORT ) || ( PROTOCOL == FRSKY_SPORT_HUB ) )
233 // used by SPORT protocol
234 void sendSportData() ;
235 uint8_t readStatusValue( uint8_t currentValueType
) ;
236 void loadSportValueToSend( uint8_t ValueTypeToLoad
) ;
237 uint8_t nextFieldToSend( uint8_t indexField
) ;
238 void FrSkySportSensorGpsSend() ;
241 #if defined( PROTOCOL ) && ( ( PROTOCOL == FRSKY_HUB ) || ( PROTOCOL == FRSKY_SPORT_HUB ) )
242 // used by Hub protocol
244 void loadHubValueToSend( uint8_t ValueTypeToLoad
) ;
247 void SendValue(uint8_t ID
, uint16_t Value
);
248 void SendCellVoltage(uint32_t voltage
);
249 void SendGPSDist(uint16_t dist
);
250 void SendTemperature1(int16_t tempc
);
251 void SendTemperature2(int16_t tempc
);
252 void SendAlt(long altcm
);
253 void SendGPSAlt(long altcm
);
254 void SendFuel(uint16_t fuel
);
255 void SendCurrentMilliAmps(int32_t milliamps
);
256 void SendGPSSpeed(long speedknots
) ;
257 void sendHubByte( uint8_t byte
) ;
258 void SendVoltX( uint8_t VoltToSend
, uint8_t indexFieldToSend
) ;
263 //extern bool ppmAvailable ;
264 extern struct ONE_MEASUREMENT ppm
;
265 extern struct ONE_MEASUREMENT mainVspeed
; // used to transmit the main Vspeed(calculated based on all set up in config)
266 extern struct ONE_MEASUREMENT compensatedClimbRate
; // used to transmit the compensated Vspeed
267 extern struct ONE_MEASUREMENT switchVSpeed
; // used to transmit the selected Vspeed
268 extern struct ONE_MEASUREMENT averageVSpeed
; // used to transmit the average Vspeed
269 extern struct ONE_MEASUREMENT vSpeedImu
; // used to transmit the Vspeedcalculated based on IMU
271 #if defined(VFAS_SOURCE)
272 extern struct ONE_MEASUREMENT vfas
;
275 extern struct ONE_MEASUREMENT test1
;
276 extern struct ONE_MEASUREMENT test2
;
277 extern struct ONE_MEASUREMENT test3
;
278 extern struct ONE_MEASUREMENT gliderRatio
;
279 extern struct ONE_MEASUREMENT secFromT0
;
280 extern struct ONE_MEASUREMENT averageVspeedSinceT0
;
282 extern uint8_t selectedVario
;
284 extern struct ONE_MEASUREMENT yaw
;
285 extern struct ONE_MEASUREMENT pitch
;
286 extern struct ONE_MEASUREMENT roll
;
290 extern volatile uint16_t RpmValue
;
291 extern bool RpmAvailable
;
292 #endif // MEASURE_RPM
294 extern OXS_ADS1115 oXs_ads1115
;
299 // **********************
300 // GPS data being read
301 // **********************
302 extern int32_t GPS_lon
; // longitude in degree with 7 decimals, (neg for S)
303 extern bool GPS_lonAvailable
;
304 extern int32_t GPS_lat
; // latitude in degree with 7 decimals, (neg for ?)
305 extern bool GPS_latAvailable
;
307 extern int32_t GPS_altitude
; // altitude in mm
308 extern bool GPS_altitudeAvailable
;
309 extern uint16_t GPS_speed_3d
; // speed in cm/s
310 extern bool GPS_speed_3dAvailable
;
311 extern uint16_t GPS_speed_2d
; // speed in cm/s
312 extern bool GPS_speed_2dAvailable
;
313 extern uint16_t GPS_speed
; // speed in cm/s
314 extern bool GPS_speedAvailable
;
315 extern uint32_t GPS_ground_course
; // degrees with 5 decimals
316 #if defined(GPS_TRANSMIT_TIME)
317 extern int16_t GPS_year
; // year
318 extern int8_t GPS_month
; // month
319 extern int8_t GPS_day
; // day
320 extern int8_t GPS_hour
; // hours
321 extern int8_t GPS_min
; // minutes
322 extern int8_t GPS_sec
; // seconds
323 extern bool GPS_timeAvailable
;
325 extern bool GPS_ground_courseAvailable
;
328 extern uint8_t GPS_numSat
;
329 extern uint16_t GPS_hdop
; // Compute GPS quality signal
330 //uint16_t GPS_packetCount = 0;
331 //uint32_t GPS_svInfoReceivedCount = 0; // SV = Space Vehicle, counter increments each time SV info is received.
332 //uint8_t GPS_update = 0; // it's a binary toggle to distinct a GPS position update
333 //uint8_t GPS_numCh; // Number of channels
334 //uint8_t GPS_svinfo_chn[GPS_SV_MAXSATS]; // Channel number
335 //uint8_t GPS_svinfo_svid[GPS_SV_MAXSATS]; // Satellite ID
336 //uint8_t GPS_svinfo_quality[GPS_SV_MAXSATS]; // Bitfield Qualtity
337 //uint8_t GPS_svinfo_cno[GPS_SV_MAXSATS]; // Carrier to Noise Ratio (Signal Strength)
338 extern bool GPS_fix
; // true if gps data are available.
339 #endif // End of GPS_INSTALLED
341 //******************* part used for handling of UART with Receiver ************************
342 extern volatile uint8_t debug01
;
343 extern volatile uint8_t debug02
;
344 extern volatile uint8_t debug03
;
345 extern volatile uint8_t debug04
;
348 // used by FRSKY_SPORT protocol
349 void setSportNewData( uint16_t id
, uint32_t value
) ;
350 void initSportUart() ;
351 void initMeasurement() ;
353 // used by Hub protocol
354 #define MAXSIZEBUFFER 70 // max size of the buffer used to store the data to be sent in the hub protocol
355 void initHubUart( ) ;
356 void setHubNewData( ) ;
357 void startHubTransmit( void ) ;
359 // used in all protocol // not sure it is used here
360 extern volatile bool RpmSet
;
361 extern volatile uint16_t RpmValue
;
363 extern volatile bool sportAvailable
;
365 uint32_t micros( void ) ;
366 uint32_t millis( void ) ;
369 #define IDLE 0 // Idle state, both transmit and receive possible.
370 #define TRANSMIT 1 // Transmitting byte.
371 #define TRANSMIT_STOP_BIT 2 // Transmitting stop bit.
372 #define RECEIVE 3 // Receiving byte.
376 // 57600 = Desired baudrate for Sport protocol = 17 micro sec per bit.
377 // 9600 = Desired baudrate for Hub protocol
378 //This section chooses the correct timer values for the Sport protocol = 57600 baud.
379 // Assumes a 16MHz clock
380 //#define TICKS2COUNT 278 // Ticks between two bits.
381 //#define TICKS2WAITONE 278 // Wait one bit period.
382 //#define TICKS2WAITONE_HALF 416 // Wait one and a half bit period.
383 #if F_CPU == 20000000L // 20MHz clock
385 #define TICKS2COUNTSPORT 348 // Ticks between two bits.
386 #define TICKS2WAITONESPORT 348 // Wait one bit period.
387 #define TICKS2WAITONE_HALFSPORT 520 // Wait one and a half bit period.
388 #elif F_CPU == 16000000L // 16MHz clock
389 #define TICKS2COUNTSPORT 278 // Ticks between two bits.
390 #define TICKS2WAITONESPORT 278 // Wait one bit period.
391 #define TICKS2WAITONE_HALFSPORT 416 // Wait one and a half bit period.
392 #elif F_CPU == 8000000L // 8MHz clock
393 // Assumes a 8MHz clock
394 #define TICKS2COUNTSPORT 139 // Ticks between two bits.
395 #define TICKS2WAITONESPORT 139 // Wait one bit period.
396 #define TICKS2WAITONE_HALFSPORT 208 // Wait one and a half bit period.
398 #error Unsupported clock speed
401 //This section chooses the correct timer values for Hub protocol = 9600 baud.
402 // Assumes a 16MHz clock
403 //#define TICKS2COUNT (278*6) // Ticks between two bits.
404 //#define TICKS2WAITONE (278*6) // Wait one bit period.
405 //#define TICKS2WAITONE_HALF (416*6) // Wait one and a half bit period.
406 #if F_CPU == 20000000L // 20MHz clock
408 #define TICKS2COUNTHUB (348*6) // Ticks between two bits.
409 #define TICKS2WAITONEHUB (348*6) // Wait one bit period.
410 #define TICKS2WAITONE_HALFHUB (520*6) // Wait one and a half bit period.
411 #elif F_CPU == 16000000L // 16MHz clock
412 #define TICKS2COUNTHUB (278*6) // Ticks between two bits.
413 #define TICKS2WAITONEHUB (278*6) // Wait one bit period.
414 #define TICKS2WAITONE_HALFHUB (416*6) // Wait one and a half bit period.
415 #elif F_CPU == 8000000L // 8MHz clock
416 #define TICKS2COUNTHUB (139*6) // Ticks between two bits.
417 #define TICKS2WAITONEHUB (139*6) // Wait one bit period.
418 #define TICKS2WAITONE_HALFHUB (208*6) // Wait one and a half bit period.
420 #error Unsupported clock speed
423 //#define INTERRUPT_EXEC_CYCL 90 // Cycles to execute interrupt routines from interrupt.
424 //#define INTERRUPT_EARLY_BIAS 32 // Cycles to allow of other interrupts.
425 // INTERRUPT_EARLY_BIAS is to bias the sample point a bit early in case
426 // the Timer 0 interrupt (5.5uS) delays the start bit detection
427 #if F_CPU == 20000000L // 20MHz clock
428 #define INTERRUPT_EXEC_CYCL 112 // Cycles to execute interrupt routines from interrupt.
429 #define INTERRUPT_EARLY_BIAS 40 // Cycles to allow of other interrupts.
430 #elif F_CPU == 16000000L // 16MHz clock
431 #define INTERRUPT_EXEC_CYCL 90 // Cycles to execute interrupt routines from interrupt.
432 #define INTERRUPT_EARLY_BIAS 32 // Cycles to allow of other interrupts.
433 #elif F_CPU == 8000000L // 8MHz clock
434 #define INTERRUPT_EXEC_CYCL 90 // Cycles to execute interrupt routines from interrupt.
435 #define INTERRUPT_EARLY_BIAS 32 // Cycles to allow of other interrupts.
437 #error Unsupported clock speed
440 #define INTERRUPT_ENTRY_TRANSMIT 59 // Cycles in ISR before sending first bit from first byte; Without this correction, first bit is sent 7.4 usec to late at 8 Mhz (so it takes 59 cycles = 7.4 usec * 8)
441 #define INTERRUPT_BETWEEN_TRANSMIT 64 // Cycles in ISR before sending first bit from 2d, 3rd... bytes; Without this correction, first bit is sent 4 usec to late at 16 Mhz (so it takes 64 cycles = 4 usec * 16)
443 // this section define some delays used in Aserial; values can be used by any protocol
444 #if F_CPU == 20000000L // 20MHz clock
445 #define DELAY_4000 ((uint16_t)4000.0 * 20.0 /16.0 )
446 #define DELAY_3500 ((uint16_t)3500.0 * 20.0 /16.0 )
447 #define DELAY_2000 ((uint16_t)2000.0 * 20.0 /16.0 )
448 #define DELAY_1600 ((uint16_t)1600.0 * 20.0 /16.0 )
449 #define DELAY_400 ((uint16_t)400.0 * 20.0 /16.0 )
450 #define DELAY_100 ((uint16_t)100.0 * 20.0 /16.0 )
451 #elif F_CPU == 16000000L // 16MHz clock
452 #define DELAY_4000 ((uint16_t) (3999L * 16) )
453 #define DELAY_3500 ((uint16_t) (3500L * 16) )
454 #define DELAY_2000 ((uint16_t) (2000L * 16) )
455 #define DELAY_1600 ((uint16_t) (1600L * 16) )
456 #define DELAY_400 ((uint16_t) (400 * 16) )
457 #define DELAY_100 ((uint16_t) (100 * 16) )
458 #elif F_CPU == 8000000L // 8MHz clock
459 #define DELAY_4000 ((uint16_t)4000L * 8 )
460 #define DELAY_3500 ((uint16_t)3500L * 8 )
461 #define DELAY_2000 ((uint16_t)2000 * 8 )
462 #define DELAY_1600 ((uint16_t)1600 * 8 )
463 #define DELAY_400 ((uint16_t)400 * 8 )
464 #define DELAY_100 ((uint16_t)100 * 8 )
466 #error Unsupported clock speed
469 #define TCCR TCCR1A //!< Timer/Counter Control Register
470 #define TCCR_P TCCR1B //!< Timer/Counter Control (Prescaler) Register
471 #define OCR OCR1A //!< Output Compare Register
472 #define EXT_IFR EIFR //!< External Interrupt Flag Register
473 #define EXT_ICR EICRA //!< External Interrupt Control Register
476 #define TRXPORT PORTD
479 #define SET_TX_PIN( ) ( TRXPORT |= ( 1 << PIN_SERIALTX ) )
480 #define CLEAR_TX_PIN( ) ( TRXPORT &= ~( 1 << PIN_SERIALTX ) )
482 #if PIN_SERIALTX == 7
483 #define GET_RX_PIN( ) ( ACSR & ( 1 << ACO ) )
485 #define GET_RX_PIN( ) ( TRXPIN & ( 1 << PIN_SERIALTX ) )
488 //******************* End of part used for handling of UART with Receiver
490 #endif // Enf of ndef MULTIPLEX