39 #include "baroaltitude.h"
40 #include "flightbatterysettings.h"
41 #include "flightbatterystate.h"
42 #include "gpsposition.h"
43 #include "modulesettings.h"
45 #if defined(PIOS_INCLUDE_FRSKY_SPORT_TELEMETRY)
47 #define FRSKY_POLL_REQUEST 0x7e
48 #define FRSKY_MINIMUM_POLL_INTERVAL 10000
51 FRSKY_STATE_WAIT_POLL_REQUEST,
52 FRSKY_STATE_WAIT_SENSOR_ID,
53 FRSKY_STATE_WAIT_TX_DONE,
84 struct frsky_sport_telemetry {
85 enum frsky_state
state;
86 int32_t scheduled_item;
87 uint32_t last_poll_time;
88 uint8_t ignore_rx_chars;
91 uint32_t item_last_triggered[
NELEMENTS(frsky_value_items)];
94 static const uint8_t frsky_sensor_ids[] = {0x1b};
96 #define FRSKY_SPORT_BAUDRATE 57600
98 #if defined(PIOS_FRSKY_SPORT_TELEMETRY_STACK_SIZE)
99 #define STACK_SIZE_BYTES PIOS_FRSKY_SPORT_TELEMETRY_STACK_SIZE
101 #define STACK_SIZE_BYTES 672
103 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
106 static struct frsky_sport_telemetry *frsky;
107 static int32_t uavoFrSKYSPortBridgeInitialize(
void);
108 static void uavoFrSKYSPortBridgeTask(
void *parameters);
114 static void frsky_schedule_next_item(
void)
117 int32_t max_exp_time = INT32_MIN;
118 int32_t most_exp_item = -1;
119 for (i = 0; i <
NELEMENTS(frsky_value_items); i++) {
120 if (frsky_value_items[i].encode_value(&frsky->frsky_settings, 0,
true, frsky_value_items[i].
fn_arg)) {
123 if (exp_time > max_exp_time) {
124 max_exp_time = exp_time;
129 frsky->scheduled_item = most_exp_item;
135 static bool frsky_send_scheduled_item(
void)
137 int32_t item = frsky->scheduled_item;
138 if ((item >= 0) && (item <
NELEMENTS(frsky_value_items))) {
141 if (frsky_value_items[item].encode_value(&frsky->frsky_settings, &value,
false,
142 frsky_value_items[item].
fn_arg)) {
143 frsky->ignore_rx_chars +=
frsky_send_frame(frsky->com, (uint16_t)(frsky_value_items[item].
id), value,
false);
155 static void frsky_receive_byte(uint8_t b)
158 switch (frsky->state) {
159 case FRSKY_STATE_WAIT_TX_DONE:
162 if (--frsky->ignore_rx_chars == 0)
163 frsky->state = FRSKY_STATE_WAIT_POLL_REQUEST;
166 case FRSKY_STATE_WAIT_POLL_REQUEST:
167 if (b == FRSKY_POLL_REQUEST) {
171 frsky->state = FRSKY_STATE_WAIT_SENSOR_ID;
176 case FRSKY_STATE_WAIT_SENSOR_ID:
177 frsky->state = FRSKY_STATE_WAIT_POLL_REQUEST;
178 for (i = 0; i <
sizeof(frsky_sensor_ids); i++) {
179 if (frsky_sensor_ids[i] == b) {
182 if (GPSPositionHandle() != NULL)
183 GPSPositionGet(&frsky->frsky_settings.gps_position);
185 if (frsky_send_scheduled_item() && frsky->ignore_rx_chars)
186 frsky->state = FRSKY_STATE_WAIT_TX_DONE;
188 frsky_schedule_next_item();
200 static int32_t uavoFrSKYSPortBridgeStart(
void)
205 if (FlightBatterySettingsHandle() != NULL
206 && FlightBatteryStateHandle() != NULL) {
208 FlightBatterySettingsCurrentPinGet(¤tPin);
209 if (currentPin != FLIGHTBATTERYSETTINGS_CURRENTPIN_NONE)
210 frsky->frsky_settings.use_current_sensor =
true;
211 FlightBatterySettingsGet(&frsky->frsky_settings.battery_settings);
212 frsky->frsky_settings.batt_cell_count = frsky->frsky_settings.battery_settings.NbCells;
214 if (BaroAltitudeHandle() != NULL
216 frsky->frsky_settings.use_baro_sensor =
true;
218 struct pios_thread *
task;
220 uavoFrSKYSPortBridgeTask,
"uavoFrSKYSPortBridge",
232 static int32_t uavoFrSKYSPortBridgeInitialize(
void)
237 frsky =
PIOS_malloc(
sizeof(
struct frsky_sport_telemetry));
239 memset(frsky, 0x00,
sizeof(
struct frsky_sport_telemetry));
241 frsky->frsky_settings.use_current_sensor =
false;
242 frsky->frsky_settings.batt_cell_count = 0;
243 frsky->frsky_settings.use_baro_sensor =
false;
244 frsky->state = FRSKY_STATE_WAIT_POLL_REQUEST;
246 frsky->ignore_rx_chars = 0;
247 frsky->scheduled_item = -1;
248 frsky->com = sport_com;
251 for (i = 0; i <
NELEMENTS(frsky_value_items); i++)
261 MODULE_INITCALL(uavoFrSKYSPortBridgeInitialize, uavoFrSKYSPortBridgeStart)
267 static
void uavoFrSKYSPortBridgeTask(
void *parameters)
273 frsky_receive_byte(b);
277 #endif //PIOS_INCLUDE_FRSKY_SPORT_TELEMETRY
Packs UAVObjects into FrSKY Smart Port frames.
bool frsky_encode_vario(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
uint32_t PIOS_DELAY_GetuS()
Query the Delay timer for the current uS.
bool frsky_encode_fuel(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_airspeed(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_gps_alt(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_gps_time(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool PIOS_Modules_IsEnabled(enum pios_modules module)
bool frsky_encode_acc(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
void * PIOS_malloc(size_t size)
bool frsky_encode_current(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_rpm(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
uint32_t PIOS_DELAY_GetuSSince(uint32_t t)
Calculate time in microseconds since a previous time.
bool frsky_encode_gps_coord(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_t2(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool PIOS_SENSORS_IsRegistered(enum pios_sensor_type type)
Checks if a sensor type is registered with the PIOS_SENSORS interface.
#define PIOS_QUEUE_TIMEOUT_MAX
#define MODULE_INITCALL(ifn, sfn)
uint16_t PIOS_COM_ReceiveBuffer(uintptr_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms)
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
static TaskInfoRunningElem task
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
int32_t frsky_send_frame(uintptr_t com, enum frsky_value_id id, uint32_t value, bool send_prelude)
bool frsky_encode_gps_speed(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_cells(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_t1(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_altitude(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_gps_course(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
#define PIOS_COM_FRSKY_SPORT
int32_t PIOS_COM_ChangeBaud(uintptr_t com_id, uint32_t baud)