5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
24 uint8_t telemetryStreaming
= 0;
25 uint8_t telemetryRxBuffer
[TELEMETRY_RX_PACKET_SIZE
]; // Receive buffer. 9 bytes (full packet), worst case 18 bytes with byte-stuffing (+1)
26 uint8_t telemetryRxBufferCount
= 0;
28 uint8_t telemetryState
= TELEMETRY_INIT
;
30 TelemetryData telemetryData
;
32 uint8_t telemetryProtocol
= 255;
34 #if defined(PCBSKY9X) && defined(REVX)
35 uint8_t serialInversion
= 0;
38 void processTelemetryData(uint8_t data
)
40 #if defined(CROSSFIRE)
41 if (telemetryProtocol
== PROTOCOL_TELEMETRY_CROSSFIRE
) {
42 processCrossfireTelemetryData(data
);
47 #if defined(MULTIMODULE)
48 if (telemetryProtocol
== PROTOCOL_TELEMETRY_SPEKTRUM
) {
49 processSpektrumTelemetryData(EXTERNAL_MODULE
, data
, telemetryRxBuffer
, telemetryRxBufferCount
);
52 if (telemetryProtocol
== PROTOCOL_TELEMETRY_FLYSKY_IBUS
) {
53 processFlySkyTelemetryData(data
, telemetryRxBuffer
, telemetryRxBufferCount
);
56 if (telemetryProtocol
== PROTOCOL_TELEMETRY_MULTIMODULE
) {
57 processMultiTelemetryData(data
, EXTERNAL_MODULE
);
62 processFrskyTelemetryData(data
);
65 inline bool isBadAntennaDetected()
67 if (!isRasValueValid())
70 if (telemetryData
.swrInternal
.isFresh() && telemetryData
.swrInternal
.value() > FRSKY_BAD_ANTENNA_THRESHOLD
)
73 if (telemetryData
.swrExternal
.isFresh() && telemetryData
.swrExternal
.value() > FRSKY_BAD_ANTENNA_THRESHOLD
)
79 void telemetryWakeup()
81 uint8_t requiredTelemetryProtocol
= modelTelemetryProtocol();
85 uint8_t requiredSerialInversion
= g_model
.moduleData
[EXTERNAL_MODULE
].invertedSerial
;
86 if (telemetryProtocol
!= requiredTelemetryProtocol
|| serialInversion
!= requiredSerialInversion
) {
87 serialInversion
= requiredSerialInversion
;
88 telemetryInit(requiredTelemetryProtocol
);
91 if (telemetryProtocol
!= requiredTelemetryProtocol
) {
92 telemetryInit(requiredTelemetryProtocol
);
96 #if defined(INTERNAL_MODULE_PXX2) || defined(EXTMODULE_USART)
97 uint8_t frame
[PXX2_FRAME_MAXLENGTH
];
99 #if defined(INTERNAL_MODULE_PXX2)
100 while (intmoduleFifo
.getFrame(frame
)) {
101 processPXX2Frame(INTERNAL_MODULE
, frame
);
105 #if defined(EXTMODULE_USART)
106 while (extmoduleFifo
.getFrame(frame
)) {
107 processPXX2Frame(EXTERNAL_MODULE
, frame
);
112 #if defined(INTERNAL_MODULE_MULTI)
113 if (intmoduleFifo
.pop(data
)) {
114 LOG_TELEMETRY_WRITE_START();
116 processMultiTelemetryData(data
, INTERNAL_MODULE
);
117 LOG_TELEMETRY_WRITE_BYTE(data
);
118 } while (intmoduleFifo
.pop(data
));
123 if (telemetryGetByte(&data
)) {
124 LOG_TELEMETRY_WRITE_START();
126 processTelemetryData(data
);
127 LOG_TELEMETRY_WRITE_BYTE(data
);
128 } while (telemetryGetByte(&data
));
130 #elif defined(PCBSKY9X)
131 if (telemetryProtocol
== PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY
) {
133 while (telemetrySecondPortReceive(data
)) {
134 processTelemetryData(data
);
138 // Receive serial data here
139 rxPdcUsart(processTelemetryData
);
143 for (int i
=0; i
<MAX_TELEMETRY_SENSORS
; i
++) {
144 const TelemetrySensor
& sensor
= g_model
.telemetrySensors
[i
];
145 if (sensor
.type
== TELEM_TYPE_CALCULATED
) {
146 telemetryItems
[i
].eval(sensor
);
151 if (TELEMETRY_STREAMING() && !IS_FAI_ENABLED()) {
156 static tmr10ms_t alarmsCheckTime
= 0;
157 #define SCHEDULE_NEXT_ALARMS_CHECK(seconds) alarmsCheckTime = get_tmr10ms() + (100*(seconds))
158 if (int32_t(get_tmr10ms() - alarmsCheckTime
) > 0) {
160 SCHEDULE_NEXT_ALARMS_CHECK(1/*second*/);
162 bool sensorLost
= false;
163 for (int i
=0; i
<MAX_TELEMETRY_SENSORS
; i
++) {
164 if (isTelemetryFieldAvailable(i
)) {
165 TelemetryItem
& item
= telemetryItems
[i
];
166 if (item
.timeout
== 0) {
167 TelemetrySensor
* sensor
= & g_model
.telemetrySensors
[i
];
168 if (sensor
->unit
!= UNIT_DATETIME
) {
176 if (sensorLost
&& TELEMETRY_STREAMING() && !g_model
.rssiAlarms
.disabled
) {
177 audioEvent(AU_SENSOR_LOST
);
180 #if defined(PCBTARANIS) || defined(PCBHORUS)
181 if (isBadAntennaDetected()) {
183 POPUP_WARNING(STR_WARNING
);
184 const char * w
= STR_ANTENNAPROBLEM
;
185 SET_WARNING_INFO(w
, strlen(w
), 0);
186 SCHEDULE_NEXT_ALARMS_CHECK(10/*seconds*/);
190 if (!g_model
.rssiAlarms
.disabled
) {
191 if (TELEMETRY_STREAMING()) {
192 if (TELEMETRY_RSSI() < g_model
.rssiAlarms
.getCriticalRssi() ) {
194 SCHEDULE_NEXT_ALARMS_CHECK(10/*seconds*/);
196 else if (TELEMETRY_RSSI() < g_model
.rssiAlarms
.getWarningRssi() ) {
198 SCHEDULE_NEXT_ALARMS_CHECK(10/*seconds*/);
202 if (TELEMETRY_STREAMING()) {
203 if (telemetryState
== TELEMETRY_KO
) {
204 AUDIO_TELEMETRY_BACK();
206 telemetryState
= TELEMETRY_OK
;
208 else if (telemetryState
== TELEMETRY_OK
) {
209 telemetryState
= TELEMETRY_KO
;
210 if (!isModuleInBeepMode()) {
211 AUDIO_TELEMETRY_LOST();
218 void telemetryInterrupt10ms()
220 if (telemetryStreaming
> 0) {
221 bool tick160ms
= (telemetryStreaming
& 0x0F) == 0;
222 for (int i
=0; i
<MAX_TELEMETRY_SENSORS
; i
++) {
223 const TelemetrySensor
& sensor
= g_model
.telemetrySensors
[i
];
224 if (sensor
.type
== TELEM_TYPE_CALCULATED
) {
225 telemetryItems
[i
].per10ms(sensor
);
227 if (tick160ms
&& telemetryItems
[i
].timeout
> 0) {
228 telemetryItems
[i
].timeout
--;
231 telemetryStreaming
--;
235 telemetryData
.rssi
.reset();
237 for (auto & telemetryItem
: telemetryItems
) {
238 if (telemetryItem
.isAvailable()) {
239 telemetryItem
.setOld();
245 void telemetryReset()
247 telemetryData
.clear();
249 for (auto & telemetryItem
: telemetryItems
) {
250 telemetryItem
.clear();
253 telemetryStreaming
= 0; // reset counter only if valid telemetry packets are being detected
255 telemetryState
= TELEMETRY_INIT
;
258 // we don't reset the telemetry here as we would also reset the consumption after model load
259 void telemetryInit(uint8_t protocol
)
261 telemetryProtocol
= protocol
;
263 if (protocol
== PROTOCOL_TELEMETRY_FRSKY_D
) {
264 telemetryPortInit(FRSKY_D_BAUDRATE
, TELEMETRY_SERIAL_DEFAULT
);
267 #if defined(MULTIMODULE)
268 else if (protocol
== PROTOCOL_TELEMETRY_MULTIMODULE
|| protocol
== PROTOCOL_TELEMETRY_FLYSKY_IBUS
) {
269 // The DIY Multi module always speaks 100000 baud regardless of the telemetry protocol in use
270 telemetryPortInit(MULTIMODULE_BAUDRATE
, TELEMETRY_SERIAL_8E2
);
272 outputTelemetryBuffer
.reset();
275 else if (protocol
== PROTOCOL_TELEMETRY_SPEKTRUM
) {
276 // Spektrum's own small race RX (SPM4648) uses 125000 8N1, use the same since there is no real standard
277 telemetryPortInit(125000, TELEMETRY_SERIAL_DEFAULT
);
281 #if defined(CROSSFIRE)
282 else if (protocol
== PROTOCOL_TELEMETRY_CROSSFIRE
) {
283 telemetryPortInit(CROSSFIRE_BAUDRATE
, TELEMETRY_SERIAL_DEFAULT
);
285 outputTelemetryBuffer
.reset();
287 telemetryPortSetDirectionOutput();
291 #if defined(AUX_SERIAL) || defined(PCBSKY9X)
292 else if (protocol
== PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY
) {
293 telemetryPortInit(0, TELEMETRY_SERIAL_DEFAULT
);
294 auxSerialTelemetryInit(PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY
);
299 telemetryPortInit(FRSKY_SPORT_BAUDRATE
, TELEMETRY_SERIAL_WITHOUT_DMA
);
301 outputTelemetryBuffer
.reset();
305 #if defined(REVX) && !defined(SIMU)
306 if (serialInversion
) {
316 #if defined(LOG_TELEMETRY) && !defined(SIMU)
317 extern FIL g_telemetryFile
;
318 void logTelemetryWriteStart()
320 static tmr10ms_t lastTime
= 0;
321 tmr10ms_t newTime
= get_tmr10ms();
322 if (lastTime
!= newTime
) {
325 f_printf(&g_telemetryFile
, "\r\n%4d-%02d-%02d,%02d:%02d:%02d.%02d0:", utm
.tm_year
+TM_YEAR_BASE
, utm
.tm_mon
+1, utm
.tm_mday
, utm
.tm_hour
, utm
.tm_min
, utm
.tm_sec
, g_ms100
);
330 void logTelemetryWriteByte(uint8_t data
)
332 f_printf(&g_telemetryFile
, " %02X", data
);
336 OutputTelemetryBuffer outputTelemetryBuffer __DMA
;
339 Fifo
<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE
> * luaInputTelemetryFifo
= NULL
;