30 #if defined(PIOS_INCLUDE_CROSSFIRE)
42 #include "modulesettings.h"
43 #include "flightbatterystate.h"
44 #include "flightbatterysettings.h"
45 #include "gpsposition.h"
46 #include "attitudeactual.h"
47 #include "manualcontrolsettings.h"
50 #define STACK_SIZE_BYTES 600 // Reevaluate.
51 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
53 #define DEG2RAD(x) ((float)x * (float)M_PI / 180.0f)
56 static struct pios_thread *uavoCrossfireTelemetryTaskHandle;
60 static uintptr_t crsf_telem_dev_id;
62 static void uavoCrossfireTelemetryTask(
void *parameters);
69 static int32_t uavoCrossfireTelemetryStart(
void)
80 uavoCrossfireTelemetryTask,
"uavoCrossfireTelemetry",
83 uavoCrossfireTelemetryTaskHandle);
91 static int32_t uavoCrossfireTelemetryInitialize(
void)
96 MODULE_INITCALL(uavoCrossfireTelemetryInitialize, uavoCrossfireTelemetryStart)
99 #define WRITE_VAL(buf,p,x) { typeof(x) v = x; uint8_t *q = (uint8_t*)&v, n = sizeof(v); do{ buf[p++] = q[--n]; } while(n); }
100 #define WRITE_VAL16(buf,p,x) { typeof(x) v = x; uint8_t *q = (uint8_t*)&v; buf[p++] = q[1]; buf[p++] = q[0]; }
101 #define WRITE_VAL32(buf,p,x) { typeof(x) v = x; uint8_t *q = (uint8_t*)&v; buf[p++] = q[3]; buf[p++] = q[2]; buf[p++] = q[1]; buf[p++] = q[0]; }
103 static int crsftelem_create_attitude(uint8_t *buf)
107 if(AttitudeActualHandle()) {
108 AttitudeActualData attitudeData;
109 AttitudeActualGet(&attitudeData);
115 WRITE_VAL16(buf, pos, (int16_t)(DEG2RAD(attitudeData.Pitch)*10000.0f));
116 WRITE_VAL16(buf, pos, (int16_t)(DEG2RAD(attitudeData.Roll)*10000.0f));
117 WRITE_VAL16(buf, pos, (int16_t)(DEG2RAD(attitudeData.Yaw)*10000.0f));
125 static int crsftelem_create_battery(uint8_t *buf)
129 if(FlightBatteryStateHandle() && FlightBatterySettingsHandle()) {
130 FlightBatteryStateData batteryData;
131 FlightBatterySettingsData batterySettings;
133 FlightBatteryStateGet(&batteryData);
134 FlightBatterySettingsGet(&batterySettings);
140 WRITE_VAL16(buf, pos, (uint16_t)(batteryData.Voltage * 10.0f))
141 WRITE_VAL16(buf, pos, (uint16_t)(batteryData.Current * 10.0
f))
144 buf[pos++] = (uint8_t)((batterySettings.Capacity & 0x00FF0000) >> 16);
145 buf[pos++] = (uint8_t)((batterySettings.Capacity & 0x0000FF00) >> 8);
146 buf[pos++] = (uint8_t)(batterySettings.Capacity & 0x000000FF);
148 float charge_state = batterySettings.Capacity == 0 ? 100.0
f : (batteryData.ConsumedEnergy / batterySettings.Capacity);
149 if(charge_state < 0) charge_state = 0;
150 else
if(charge_state > 100) charge_state = 100;
151 buf[pos++] = (uint8_t)charge_state;
159 static
int crsftelem_create_gps(uint8_t *buf)
163 if(GPSPositionHandle()) {
164 GPSPositionData gpsData;
165 GPSPositionGet(&gpsData);
167 if(gpsData.Status >= GPSPOSITION_STATUS_FIX2D) {
173 WRITE_VAL32(buf, pos, (int32_t)gpsData.Latitude);
175 WRITE_VAL32(buf, pos, (int32_t)gpsData.Longitude);
177 WRITE_VAL16(buf, pos, (uint16_t)(gpsData.Groundspeed*10.0f));
179 WRITE_VAL16(buf, pos, (uint16_t)(gpsData.Heading*100.0f));
181 WRITE_VAL16(buf, pos, (uint16_t)(1000.0
f+
182 (gpsData.Status >= GPSPOSITION_STATUS_FIX3D ? gpsData.Altitude : 0.0f)));
184 buf[pos++] = gpsData.Satellites;
193 static void uavoCrossfireTelemetryTask(
void *parameters)
196 uint32_t idledelay = 1000 / (3 *
UPDATE_HZ);
208 switch(counter++ % 3) {
211 len = crsftelem_create_attitude(buf);
214 len = crsftelem_create_battery(buf);
217 len = crsftelem_create_gps(buf);
235 #endif // PIOS_INCLUDE_CROSSFIRE
int PIOS_Crossfire_SendTelemetry(uintptr_t crsf_id, uint8_t *buf, uint8_t bytes)
#define CRSF_FRAME_BATTERY
#define CRSF_PAYLOAD_ATTITUDE
#define CRSF_PAYLOAD_LEN(x)
Main PiOS header to include all the compiled in PiOS options.
#define CRSF_PAYLOAD_BATTERY
bool PIOS_Modules_IsEnabled(enum pios_modules module)
#define CRSF_MAX_FRAMELEN
#define MODULE_INITCALL(ifn, sfn)
int PIOS_Crossfire_InitTelemetry(uintptr_t crsf_id)
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
uint8_t PIOS_CRC_updateCRC_TBS(uint8_t crc, const uint8_t *data, int32_t length)
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
uintptr_t PIOS_RCVR_GetLowerDevice(uintptr_t rcvr_id)
#define CRSF_FRAME_ATTITUDE
void PIOS_Thread_Sleep(uint32_t time_ms)
uintptr_t PIOS_HAL_GetReceiver(int receiver_type)
Includes PiOS and core architecture components.
bool PIOS_Crossfire_IsFailsafed()
if(BaroAltitudeHandle()!=NULL)