37 #include "physical_constants.h"
38 #include "modulesettings.h"
39 #include "flightbatterysettings.h"
40 #include "flightbatterystate.h"
41 #include "gpsposition.h"
42 #include "airspeedactual.h"
43 #include "baroaltitude.h"
44 #include "homelocation.h"
46 #include "flightstatus.h"
48 #include "velocityactual.h"
49 #include "attitudeactual.h"
53 #if defined(PIOS_INCLUDE_FRSKY_SENSOR_HUB)
57 static void uavoFrSKYSensorHubBridgeTask(
void *parameters);
101 uint8_t *serial_buf);
104 uint8_t *serial_buf);
121 #if defined(PIOS_FRSKY_SENSOR_HUB_STACK_SIZE)
122 #define STACK_SIZE_BYTES PIOS_FRSKY_SENSOR_HUB_STACK_SIZE
124 #define STACK_SIZE_BYTES 672
127 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
128 #define TASK_RATE_HZ 10
130 #define FRSKY_MAX_PACKET_LEN 106
131 #define FRSKY_BAUD_RATE 9600
133 #define FRSKY_FRAME_DATA_HEADER 0x5E
134 #define FRSKY_FRAME_STOP 0x5E
136 enum FRSKY_VALUE_ID {
137 FRSKY_GPS_ALTITUDE_INTEGER = 0x01,
138 FRSKY_GPS_ALTITUDE_DECIMAL = FRSKY_GPS_ALTITUDE_INTEGER + 8,
139 FRSKY_TEMPERATURE_1 = 0x02,
141 FRSKY_FUEL_LEVEL = 0x04,
142 FRSKY_TEMPERATURE_2 = 0x05,
143 FRSKY_VOLTAGE = 0x06,
144 FRSKY_ALTITUDE_INTEGER = 0x10,
145 FRSKY_ALTITUDE_DECIMAL = 0x21,
146 FRSKY_GPS_SPEED_INTEGER = 0x11,
147 FRSKY_GPS_SPEED_DECIMAL = 0x11 + 8,
148 FRSKY_GPS_LONGITUDE_INTEGER = 0x12,
149 FRSKY_GPS_LONGITUDE_DECIMAL = FRSKY_GPS_LONGITUDE_INTEGER + 8,
150 FRSKY_GPS_E_W = 0x1A + 8,
151 FRSKY_GPS_LATITUDE_INTEGER = 0x13,
152 FRSKY_GPS_LATITUDE_DECIMAL = FRSKY_GPS_LATITUDE_INTEGER + 8,
153 FRSKY_GPS_N_S = 0x1B + 8,
154 FRSKY_GPS_COURSE_INTEGER = 0x14,
155 FRSKY_GPS_COURSE_DECIMAL = FRSKY_GPS_COURSE_INTEGER + 8,
156 FRSKY_DATE_MONTH = 0x15,
157 FRSKY_DATE_YEAR = 0x16,
158 FRSKY_HOUR_MINUTE = 0x17,
160 FRSKY_ACCELERATION_X = 0x24,
161 FRSKY_ACCELERATION_Y = 0x25,
162 FRSKY_ACCELERATION_Z = 0x26,
163 FRSKY_VOLTAGE_AMPERE_SENSOR_INTEGER = 0x3A,
164 FRSKY_VOLTAGE_AMPERE_SENSOR_DECIMAL = 0x3B,
165 FRSKY_CURRENT = 0x28,
174 static const uint8_t frsky_rates[] = {
175 [FRSKY_FRAME_VARIO] = 0x05,
176 [FRSKY_FRAME_BATTERY] = 0x05,
177 [FRSKY_FRAME_GPS] = 0x01
180 #define MAXSTREAMS sizeof(frsky_rates)
187 struct pios_thread *task_handle;
193 uint8_t serial_buf[FRSKY_MAX_PACKET_LEN];
201 static int32_t uavoFrSKYSensorHubBridgeStart(
void)
206 uavoFrSKYSensorHubBridgeTask,
"uavoFrSKYSensorHubBridge",
209 shub_global->task_handle);
220 static int32_t uavoFrSKYSensorHubBridgeInitialize(
void)
227 if (shub_global == 0) {
231 shub_global->frsky_port = frsky_port;
236 shub_global->frame_ticks[x] =
246 MODULE_INITCALL(uavoFrSKYSensorHubBridgeInitialize, uavoFrSKYSensorHubBridgeStart)
251 static
void uavoFrSKYSensorHubBridgeTask(
void *parameters)
253 FlightBatterySettingsData batSettings;
254 FlightBatteryStateData batState;
255 GPSPositionData gpsPosData;
256 BaroAltitudeData baroAltitude;
257 FlightStatusData flightStatus;
261 if (FlightBatterySettingsHandle() != NULL )
262 FlightBatterySettingsGet(&batSettings);
264 batSettings.Capacity = 0;
265 batSettings.SensorCalibrationFactor[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONFACTOR_CURRENT] = 0;
266 batSettings.SensorCalibrationFactor[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONFACTOR_VOLTAGE] = 0;
267 batSettings.CellVoltageThresholds[FLIGHTBATTERYSETTINGS_CELLVOLTAGETHRESHOLDS_WARNING] = 0;
268 batSettings.CellVoltageThresholds[FLIGHTBATTERYSETTINGS_CELLVOLTAGETHRESHOLDS_ALARM] = 0;
269 batSettings.NbCells = 0;
270 batSettings.VoltagePin = FLIGHTBATTERYSETTINGS_VOLTAGEPIN_NONE;
271 batSettings.CurrentPin = FLIGHTBATTERYSETTINGS_CURRENTPIN_NONE;
274 if (GPSPositionHandle() == NULL ) {
275 gpsPosData.Altitude = 0;
276 gpsPosData.GeoidSeparation = 0;
277 gpsPosData.Groundspeed = 0;
279 gpsPosData.Heading = 0;
280 gpsPosData.Latitude = 0;
281 gpsPosData.Longitude = 0;
283 gpsPosData.Satellites = 0;
284 gpsPosData.Status = 0;
288 if (FlightBatteryStateHandle() == NULL ) {
289 batState.AvgCurrent = 0;
290 batState.BoardSupplyVoltage = 0;
291 batState.ConsumedEnergy = 0;
292 batState.Current = 0;
293 batState.EstimatedFlightTime = 0;
294 batState.PeakCurrent = 0;
295 batState.Voltage = 0;
298 uint8_t
last_armed = FLIGHTSTATUS_ARMED_DISARMED;
299 float altitude_offset = 0.0f;
313 uint8_t accelDataSettings;
314 ModuleSettingsFrskyAccelDataGet(&accelDataSettings);
315 switch(accelDataSettings) {
316 case MODULESETTINGS_FRSKYACCELDATA_ACCELS: {
317 if (AccelsHandle() != NULL) {
324 case MODULESETTINGS_FRSKYACCELDATA_NEDACCELS: {
325 if (NedAccelHandle() != NULL) {
326 NedAccelNorthGet(&accX);
327 NedAccelEastGet(&
accY);
328 NedAccelDownGet(&
accZ);
332 case MODULESETTINGS_FRSKYACCELDATA_NEDVELOCITY: {
333 if (VelocityActualHandle() != NULL) {
334 VelocityActualNorthGet(&accX);
335 VelocityActualEastGet(&
accY);
336 VelocityActualDownGet(&
accZ);
337 accX *= GRAVITY / 10.0f;
338 accY *= GRAVITY / 10.0f;
339 accZ *= GRAVITY / 10.0f;
345 if (AttitudeActualHandle() != NULL) {
346 AttitudeActualRollGet(&accX);
349 accX *= GRAVITY / 10.0f;
350 accY *= GRAVITY / 10.0f;
361 shub_global->serial_buf + msg_length);
363 if (BaroAltitudeHandle() != NULL)
364 BaroAltitudeGet(&baroAltitude);
366 FlightStatusGet(&flightStatus);
369 if ((flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMING) ||
370 ((last_armed != FLIGHTSTATUS_ARMED_ARMED) && (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED))) {
371 altitude_offset = baroAltitude.Altitude;
373 last_armed = flightStatus.Armed;
375 float altitude = baroAltitude.Altitude - altitude_offset;
378 shub_global->serial_buf + msg_length);
383 shub_global->serial_buf, msg_length);
389 if (FlightBatteryStateHandle() != NULL)
390 FlightBatteryStateGet(&batState);
393 if (batSettings.VoltagePin != FLIGHTBATTERYSETTINGS_VOLTAGEPIN_NONE)
394 voltage = batState.Voltage;
397 if (batSettings.CurrentPin != FLIGHTBATTERYSETTINGS_CURRENTPIN_NONE)
398 current = batState.Current;
403 uint8_t cellCount = batState.DetectedCellCount;
405 batSettings.NbCells = cellCount;
407 if (batSettings.NbCells > 0) {
408 float cell_v = voltage / batSettings.NbCells;
409 for(uint8_t
i = 0;
i < batSettings.NbCells; ++
i) {
413 shub_global->serial_buf + msg_length);
420 shub_global->serial_buf + msg_length);
422 if (batSettings.Capacity > 0) {
423 float fuel = 1.0f - batState.ConsumedEnergy / batSettings.Capacity;
426 shub_global->serial_buf + msg_length);
432 shub_global->serial_buf, msg_length);
447 FlightStatusData flight_status;
448 FlightStatusGet(&flight_status);
453 status = (flight_status.Armed == FLIGHTSTATUS_ARMED_ARMED) ? 200 : 100;
454 status += flight_status.FlightMode;
456 msg_length +=
frsky_pack_rpm(status, shub_global->serial_buf + msg_length);
458 uint8_t hl_set = HOMELOCATION_SET_FALSE;
460 if (GPSPositionHandle() != NULL)
461 GPSPositionGet(&gpsPosData);
463 if (HomeLocationHandle() != NULL)
464 HomeLocationSetGet(&hl_set);
476 switch (gpsPosData.Status) {
477 case GPSPOSITION_STATUS_NOGPS:
480 case GPSPOSITION_STATUS_NOFIX:
483 case GPSPOSITION_STATUS_FIX2D:
486 case GPSPOSITION_STATUS_FIX3D:
487 case GPSPOSITION_STATUS_DIFF3D:
488 if (hl_set == HOMELOCATION_SET_TRUE)
495 if (gpsPosData.Satellites > 0)
496 status += gpsPosData.Satellites;
506 hdop = gpsPosData.HDOP * 100.0f;
511 vdop = gpsPosData.VDOP * 100.0f;
518 if (gpsPosData.Status == GPSPOSITION_STATUS_FIX2D ||
519 gpsPosData.Status == GPSPOSITION_STATUS_FIX3D) {
523 gpsPosData.Longitude,
525 gpsPosData.Groundspeed,
526 shub_global->serial_buf + msg_length);
532 shub_global->serial_buf, msg_length);
539 uint8_t
rate = frsky_rates[frame_num];
545 if (shub_global->frame_ticks[frame_num] == 0) {
555 shub_global->frame_ticks[frame_num]--;
567 float altitudeInteger = 0.0f;
569 uint16_t decimalValue = lroundf(modff(altitude, &altitudeInteger) * 100);
570 int16_t integerValue = lroundf(altitude);
583 float temperature_01,
588 int16_t temperature = lroundf(temperature_01);
599 float temperature_02,
604 int16_t temperature = lroundf(temperature_02);
644 uint16_t v = lroundf((cell_voltage / 4.2
f) * 2100);
648 uint16_t
voltage = ((v & 0x00ff) << 8) | (cell << 4) | ((v & 0x0f00) >> 8);
664 voltage = (voltage * 110.0f) / 21.0
f;
666 uint16_t integerValue = lroundf(voltage) / 100;
667 uint16_t decimalValue = lroundf(voltage - integerValue);
669 frsky_serialize_value(FRSKY_VOLTAGE_AMPERE_SENSOR_INTEGER, (uint8_t*)&integerValue, serial_buf, &index);
670 frsky_serialize_value(FRSKY_VOLTAGE_AMPERE_SENSOR_DECIMAL, (uint8_t*)&decimalValue, serial_buf, &index);
672 integerValue = lroundf(current * 10);
701 uint16_t
level = lroundf(abs(fuel_level * 100));
735 float courseInteger = 0.0f;
736 uint16_t decimalValue = lroundf(modff(course, &courseInteger) * 100);
737 uint16_t integerValue = lroundf(courseInteger);
745 uint16_t integerValue = (abs(latitude) / 100000);
746 uint16_t decimalValue = (abs(latitude) / 10) % 10000;
751 uint16_t hemisphere =
'N';
760 uint16_t integerValue = (abs(longitude) / 100000);
761 uint16_t decimalValue = (abs(longitude) / 10) % 10000;
763 uint16_t hemisphere =
'E';
776 float knots = speed / KNOTS2M_PER_SECOND;
778 float knotsInteger = 0.0f;
779 uint16_t decimalValue = lroundf(modff(knots, &knotsInteger) * 100);
780 int16_t integerValue = lroundf(knotsInteger);
788 float altitudeInteger = 0.0;
789 uint16_t decimalValue = lroundf(modff(altitude, &altitudeInteger) * 100);
790 int16_t integerValue = lroundf(altitudeInteger);
805 serial_buf[0] = FRSKY_FRAME_STOP;
816 accel = accel / GRAVITY;
818 return lroundf(accel);
826 serial_buf[(*index)++] = FRSKY_FRAME_DATA_HEADER;
827 serial_buf[(*index)++] = valueid;
839 if ((byte == 0x5E) || (byte == 0x5D)) {
840 serial_buf[(*index)++] = 0x5D;
841 serial_buf[(*index)++] = ~(byte ^ 0x60);
844 serial_buf[(*index)++] = byte;
uint32_t PIOS_Thread_Systime(void)
static uint16_t frsky_pack_temperature_01(float temperature_01, uint8_t *serial_buf)
Main PiOS header to include all the compiled in PiOS options.
static uint16_t frsky_pack_fuel(float fuel_level, uint8_t *serial_buf)
#define PIOS_COM_FRSKY_SENSOR_HUB
bool PIOS_Modules_IsEnabled(enum pios_modules module)
static bool frame_trigger(uint8_t frame_num)
void * PIOS_malloc(size_t size)
static uint16_t frsky_pack_stop(uint8_t *serial_buf)
static uint16_t frsky_pack_gps(float course, int32_t latitude, int32_t longitude, float altitude, float speed, uint8_t *serial_buf)
static uint16_t frsky_pack_altitude(float altitude, uint8_t *serial_buf)
AttitudeActualPitchGet & accY
#define MODULE_INITCALL(ifn, sfn)
static int16_t frsky_acceleration_unit(float accel)
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
struct _msp_pid_item level
case MODULESETTINGS_FRSKYACCELDATA_ATTITUDEANGLES
void PIOS_Thread_Sleep_Until(uint32_t *previous_ms, uint32_t increment_ms)
static uint16_t frsky_pack_accel(float accels_x, float accels_y, float accels_z, uint8_t *serial_buf)
static uint16_t frsky_pack_fas(float voltage, float current, uint8_t *serial_buf)
static void frsky_serialize_value(uint8_t valueid, uint8_t *value, uint8_t *serial_buf, uint8_t *index)
PIOS_COM_SendBuffer(shub_global->frsky_port, shub_global->serial_buf, msg_length)
static uint16_t frsky_pack_temperature_02(float temperature_02, uint8_t *serial_buf)
static void frsky_write_userdata_byte(uint8_t byte, uint8_t *serial_buf, uint8_t *index)
Includes PiOS and core architecture components.
static uint16_t frsky_pack_rpm(uint16_t rpm, uint8_t *serial_buf)
static uint16_t frsky_pack_cellvoltage(uint8_t cell, float cell_voltage, uint8_t *serial_buf)
static uint32_t lastSysTime
AttitudeActualYawGet & accZ
int32_t PIOS_COM_ChangeBaud(uintptr_t com_id, uint32_t baud)