mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-21 09:53:35 +08:00
Merged master
This commit is contained in:
@@ -94,6 +94,9 @@ controls_tick() {
|
||||
* other. Don't do that.
|
||||
*/
|
||||
|
||||
/* receive signal strenght indicator (RSSI). 0 = no connection, 1000: perfect connection */
|
||||
uint16_t rssi = 0;
|
||||
|
||||
perf_begin(c_gather_dsm);
|
||||
uint16_t temp_count = r_raw_rc_count;
|
||||
bool dsm_updated = dsm_input(r_raw_rc_values, &temp_count);
|
||||
@@ -104,14 +107,15 @@ controls_tick() {
|
||||
r_status_flags |= PX4IO_P_STATUS_FLAGS_RC_DSM11;
|
||||
else
|
||||
r_status_flags &= ~PX4IO_P_STATUS_FLAGS_RC_DSM11;
|
||||
|
||||
rssi = 1000;
|
||||
}
|
||||
perf_end(c_gather_dsm);
|
||||
|
||||
perf_begin(c_gather_sbus);
|
||||
bool sbus_updated = sbus_input(r_raw_rc_values, &r_raw_rc_count, PX4IO_CONTROL_CHANNELS /* XXX this should be INPUT channels, once untangled */);
|
||||
bool sbus_updated = sbus_input(r_raw_rc_values, &r_raw_rc_count, &rssi, PX4IO_CONTROL_CHANNELS /* XXX this should be INPUT channels, once untangled */);
|
||||
if (sbus_updated) {
|
||||
r_status_flags |= PX4IO_P_STATUS_FLAGS_RC_SBUS;
|
||||
r_raw_rc_count = 8;
|
||||
}
|
||||
perf_end(c_gather_sbus);
|
||||
|
||||
@@ -122,10 +126,19 @@ controls_tick() {
|
||||
*/
|
||||
perf_begin(c_gather_ppm);
|
||||
bool ppm_updated = ppm_input(r_raw_rc_values, &r_raw_rc_count);
|
||||
if (ppm_updated)
|
||||
if (ppm_updated) {
|
||||
|
||||
/* XXX sample RSSI properly here */
|
||||
rssi = 1000;
|
||||
|
||||
r_status_flags |= PX4IO_P_STATUS_FLAGS_RC_PPM;
|
||||
}
|
||||
perf_end(c_gather_ppm);
|
||||
|
||||
/* limit number of channels to allowable data size */
|
||||
if (r_raw_rc_count > PX4IO_INPUT_CHANNELS)
|
||||
r_raw_rc_count = PX4IO_INPUT_CHANNELS;
|
||||
|
||||
/*
|
||||
* In some cases we may have received a frame, but input has still
|
||||
* been lost.
|
||||
@@ -221,7 +234,7 @@ controls_tick() {
|
||||
* This might happen if a protocol-based receiver returns an update
|
||||
* that contains no channels that we have mapped.
|
||||
*/
|
||||
if (assigned_channels == 0) {
|
||||
if (assigned_channels == 0 || rssi == 0) {
|
||||
rc_input_lost = true;
|
||||
} else {
|
||||
/* set RC OK flag */
|
||||
|
||||
@@ -195,7 +195,7 @@ mixer_tick(void)
|
||||
r_page_servos[i] = r_page_servo_failsafe[i];
|
||||
|
||||
/* safe actuators for FMU feedback */
|
||||
r_page_actuators[i] = (r_page_servos[i] - 1500) / 600.0f;
|
||||
r_page_actuators[i] = FLOAT_TO_REG((r_page_servos[i] - 1500) / 600.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -211,6 +211,10 @@ mixer_tick(void)
|
||||
|
||||
for (unsigned i = mixed; i < PX4IO_SERVO_COUNT; i++)
|
||||
r_page_servos[i] = 0;
|
||||
|
||||
for (unsigned i = 0; i < PX4IO_SERVO_COUNT; i++) {
|
||||
r_page_actuators[i] = FLOAT_TO_REG(outputs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((should_arm || should_always_enable_pwm) && !mixer_servos_armed) {
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
#define PX4IO_P_STATUS_VSERVO 6 /* [2] servo rail voltage in mV */
|
||||
#define PX4IO_P_STATUS_VRSSI 7 /* [2] RSSI voltage */
|
||||
#define PX4IO_P_STATUS_PRSSI 8 /* [2] RSSI PWM value */
|
||||
#define PX4IO_P_STATUS_NRSSI 9 /* [2] Normalized RSSI value, 0: no reception, 1000: perfect reception */
|
||||
|
||||
/* array of post-mix actuator outputs, -10000..10000 */
|
||||
#define PX4IO_PAGE_ACTUATORS 2 /* 0..CONFIG_ACTUATOR_COUNT-1 */
|
||||
@@ -190,6 +191,11 @@ enum { /* DSM bind states */
|
||||
/* 8 */
|
||||
#define PX4IO_P_SETUP_SET_DEBUG 9 /* debug level for IO board */
|
||||
|
||||
#define PX4IO_P_SETUP_REBOOT_BL 10 /* reboot IO into bootloader */
|
||||
#define PX4IO_REBOOT_BL_MAGIC 14662 /* required argument for reboot (random) */
|
||||
|
||||
#define PX4IO_P_SETUP_CRC 11 /* get CRC of IO firmware */
|
||||
|
||||
/* autopilot control values, -10000..10000 */
|
||||
#define PX4IO_PAGE_CONTROLS 51 /**< actuator control groups, one after the other, 8 wide */
|
||||
#define PX4IO_P_CONTROLS_GROUP_0 (PX4IO_PROTOCOL_MAX_CONTROL_COUNT * 0) /**< 0..PX4IO_PROTOCOL_MAX_CONTROL_COUNT - 1 */
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <crc32.h>
|
||||
|
||||
#include <drivers/drv_pwm_output.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
@@ -124,6 +125,22 @@ heartbeat_blink(void)
|
||||
LED_BLUE(heartbeat = !heartbeat);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
calculate_fw_crc(void)
|
||||
{
|
||||
#define APP_SIZE_MAX 0xf000
|
||||
#define APP_LOAD_ADDRESS 0x08001000
|
||||
// compute CRC of the current firmware
|
||||
uint32_t sum = 0;
|
||||
for (unsigned p = 0; p < APP_SIZE_MAX; p += 4) {
|
||||
uint32_t bytes = *(uint32_t *)(p + APP_LOAD_ADDRESS);
|
||||
sum = crc32part((uint8_t *)&bytes, sizeof(bytes), sum);
|
||||
}
|
||||
r_page_setup[PX4IO_P_SETUP_CRC] = sum & 0xFFFF;
|
||||
r_page_setup[PX4IO_P_SETUP_CRC+1] = sum >> 16;
|
||||
}
|
||||
|
||||
int
|
||||
user_start(int argc, char *argv[])
|
||||
{
|
||||
@@ -136,6 +153,9 @@ user_start(int argc, char *argv[])
|
||||
/* configure the high-resolution time/callout interface */
|
||||
hrt_init();
|
||||
|
||||
/* calculate our fw CRC so FMU can decide if we need to update */
|
||||
calculate_fw_crc();
|
||||
|
||||
/*
|
||||
* Poll at 1ms intervals for received bytes that have not triggered
|
||||
* a DMA event.
|
||||
|
||||
@@ -213,7 +213,7 @@ extern int dsm_init(const char *device);
|
||||
extern bool dsm_input(uint16_t *values, uint16_t *num_values);
|
||||
extern void dsm_bind(uint16_t cmd, int pulses);
|
||||
extern int sbus_init(const char *device);
|
||||
extern bool sbus_input(uint16_t *values, uint16_t *num_values, uint16_t max_channels);
|
||||
extern bool sbus_input(uint16_t *values, uint16_t *num_values, uint16_t *rssi, uint16_t max_channels);
|
||||
|
||||
/** global debug level for isr_debug() */
|
||||
extern volatile uint8_t debug_level;
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <drivers/drv_pwm_output.h>
|
||||
#include <systemlib/systemlib.h>
|
||||
#include <stm32_pwr.h>
|
||||
|
||||
#include "px4io.h"
|
||||
#include "protocol.h"
|
||||
@@ -154,6 +156,8 @@ volatile uint16_t r_page_setup[] =
|
||||
[PX4IO_P_SETUP_VBATT_SCALE] = 10000,
|
||||
#endif
|
||||
[PX4IO_P_SETUP_SET_DEBUG] = 0,
|
||||
[PX4IO_P_SETUP_REBOOT_BL] = 0,
|
||||
[PX4IO_P_SETUP_CRC ... (PX4IO_P_SETUP_CRC+1)] = 0,
|
||||
};
|
||||
|
||||
#define PX4IO_P_SETUP_FEATURES_VALID (0)
|
||||
@@ -501,6 +505,29 @@ registers_set_one(uint8_t page, uint8_t offset, uint16_t value)
|
||||
isr_debug(0, "set debug %u\n", (unsigned)r_page_setup[PX4IO_P_SETUP_SET_DEBUG]);
|
||||
break;
|
||||
|
||||
case PX4IO_P_SETUP_REBOOT_BL:
|
||||
if ((r_status_flags & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) ||
|
||||
(r_status_flags & PX4IO_P_STATUS_FLAGS_OVERRIDE) ||
|
||||
(r_setup_arming & PX4IO_P_SETUP_ARMING_FMU_ARMED)) {
|
||||
// don't allow reboot while armed
|
||||
break;
|
||||
}
|
||||
|
||||
// check the magic value
|
||||
if (value != PX4IO_REBOOT_BL_MAGIC)
|
||||
break;
|
||||
|
||||
// note that we don't set BL_WAIT_MAGIC in
|
||||
// BKP_DR1 as that is not necessary given the
|
||||
// timing of the forceupdate command. The
|
||||
// bootloader on px4io waits for enough time
|
||||
// anyway, and this method works with older
|
||||
// bootloader versions (tested with both
|
||||
// revision 3 and revision 4).
|
||||
|
||||
up_systemreset();
|
||||
break;
|
||||
|
||||
case PX4IO_P_SETUP_DSM:
|
||||
dsm_bind(value & 0x0f, (value >> 4) & 7);
|
||||
break;
|
||||
|
||||
@@ -54,6 +54,27 @@
|
||||
|
||||
#define SBUS_FRAME_SIZE 25
|
||||
#define SBUS_INPUT_CHANNELS 16
|
||||
#define SBUS_FLAGS_BYTE 23
|
||||
#define SBUS_FAILSAFE_BIT 3
|
||||
#define SBUS_FRAMELOST_BIT 2
|
||||
|
||||
/*
|
||||
Measured values with Futaba FX-30/R6108SB:
|
||||
-+100% on TX: PCM 1.100/1.520/1.950ms -> SBus raw values: 350/1024/1700 (100% ATV)
|
||||
-+140% on TX: PCM 0.930/1.520/2.112ms -> SBus raw values: 78/1024/1964 (140% ATV)
|
||||
-+152% on TX: PCM 0.884/1.520/2.160ms -> SBus raw values: 1/1024/2047 (140% ATV plus dirty tricks)
|
||||
*/
|
||||
|
||||
/* define range mapping here, -+100% -> 1000..2000 */
|
||||
#define SBUS_RANGE_MIN 200.0f
|
||||
#define SBUS_RANGE_MAX 1800.0f
|
||||
|
||||
#define SBUS_TARGET_MIN 1000.0f
|
||||
#define SBUS_TARGET_MAX 2000.0f
|
||||
|
||||
/* pre-calculate the floating point stuff as far as possible at compile time */
|
||||
#define SBUS_SCALE_FACTOR ((SBUS_TARGET_MAX - SBUS_TARGET_MIN) / (SBUS_RANGE_MAX - SBUS_RANGE_MIN))
|
||||
#define SBUS_SCALE_OFFSET (int)(SBUS_TARGET_MIN - (SBUS_SCALE_FACTOR * SBUS_RANGE_MIN + 0.5f))
|
||||
|
||||
static int sbus_fd = -1;
|
||||
|
||||
@@ -66,7 +87,7 @@ static unsigned partial_frame_count;
|
||||
|
||||
unsigned sbus_frame_drops;
|
||||
|
||||
static bool sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint16_t max_channels);
|
||||
static bool sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint16_t *rssi, uint16_t max_channels);
|
||||
|
||||
int
|
||||
sbus_init(const char *device)
|
||||
@@ -97,7 +118,7 @@ sbus_init(const char *device)
|
||||
}
|
||||
|
||||
bool
|
||||
sbus_input(uint16_t *values, uint16_t *num_values, uint16_t max_channels)
|
||||
sbus_input(uint16_t *values, uint16_t *num_values, uint16_t *rssi, uint16_t max_channels)
|
||||
{
|
||||
ssize_t ret;
|
||||
hrt_abstime now;
|
||||
@@ -154,7 +175,7 @@ sbus_input(uint16_t *values, uint16_t *num_values, uint16_t max_channels)
|
||||
* decode it.
|
||||
*/
|
||||
partial_frame_count = 0;
|
||||
return sbus_decode(now, values, num_values, max_channels);
|
||||
return sbus_decode(now, values, num_values, rssi, max_channels);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -194,7 +215,7 @@ static const struct sbus_bit_pick sbus_decoder[SBUS_INPUT_CHANNELS][3] = {
|
||||
};
|
||||
|
||||
static bool
|
||||
sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint16_t max_values)
|
||||
sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint16_t *rssi, uint16_t max_values)
|
||||
{
|
||||
/* check frame boundary markers to avoid out-of-sync cases */
|
||||
if ((frame[0] != 0x0f) || (frame[24] != 0x00)) {
|
||||
@@ -202,15 +223,6 @@ sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if the failsafe or connection lost bit is set, we consider the frame invalid */
|
||||
if ((frame[23] & (1 << 2)) && /* signal lost */
|
||||
(frame[23] & (1 << 3))) { /* failsafe */
|
||||
|
||||
/* actively announce signal loss */
|
||||
*values = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* we have received something we think is a frame */
|
||||
last_frame_time = frame_time;
|
||||
|
||||
@@ -234,8 +246,9 @@ sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint
|
||||
}
|
||||
}
|
||||
|
||||
/* convert 0-2048 values to 1000-2000 ppm encoding in a very sloppy fashion */
|
||||
values[channel] = (value / 2) + 998;
|
||||
|
||||
/* convert 0-2048 values to 1000-2000 ppm encoding in a not too sloppy fashion */
|
||||
values[channel] = (uint16_t)(value * SBUS_SCALE_FACTOR +.5f) + SBUS_SCALE_OFFSET;
|
||||
}
|
||||
|
||||
/* decode switch channels if data fields are wide enough */
|
||||
@@ -243,13 +256,31 @@ sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint
|
||||
chancount = 18;
|
||||
|
||||
/* channel 17 (index 16) */
|
||||
values[16] = (frame[23] & (1 << 0)) * 1000 + 998;
|
||||
values[16] = (frame[SBUS_FLAGS_BYTE] & (1 << 0)) * 1000 + 998;
|
||||
/* channel 18 (index 17) */
|
||||
values[17] = (frame[23] & (1 << 1)) * 1000 + 998;
|
||||
values[17] = (frame[SBUS_FLAGS_BYTE] & (1 << 1)) * 1000 + 998;
|
||||
}
|
||||
|
||||
/* note the number of channels decoded */
|
||||
*num_values = chancount;
|
||||
|
||||
/* decode and handle failsafe and frame-lost flags */
|
||||
if (frame[SBUS_FLAGS_BYTE] & (1 << SBUS_FAILSAFE_BIT)) { /* failsafe */
|
||||
/* report that we failed to read anything valid off the receiver */
|
||||
*rssi = 0;
|
||||
return false;
|
||||
}
|
||||
else if (frame[SBUS_FLAGS_BYTE] & (1 << SBUS_FRAMELOST_BIT)) { /* a frame was lost */
|
||||
/* set a special warning flag or try to calculate some kind of RSSI information - to be implemented
|
||||
*
|
||||
* Attention! This flag indicates a skipped frame only, not a total link loss! Handling this
|
||||
* condition as fail-safe greatly reduces the reliability and range of the radio link,
|
||||
* e.g. by prematurely issueing return-to-launch!!! */
|
||||
|
||||
*rssi = 100; // XXX magic number indicating bad signal, but not a signal loss (yet)
|
||||
}
|
||||
|
||||
*rssi = 1000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user