mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-24 22:05:58 +08:00
Merge remote-tracking branch 'paparazzi/master' into pprzlink
fix conflicts and update bluegiga datalink event
This commit is contained in:
@@ -68,8 +68,8 @@
|
||||
<arg flag="-speech" />
|
||||
</program>
|
||||
<program name="NatNet">
|
||||
<arg flag="-ac" constant="1"/>
|
||||
<arg flag="12"/>
|
||||
<arg flag="-ac" constant="7"/>
|
||||
<arg flag="114"/>
|
||||
<arg flag="-small"/>
|
||||
<arg flag="-tf" constant="5"/>
|
||||
</program>
|
||||
|
||||
@@ -72,6 +72,12 @@
|
||||
<field name="z" type="float" unit="m/s"/>
|
||||
<field name="noise" type="float"/>
|
||||
</message>
|
||||
|
||||
<message name="RSSI" id="13">
|
||||
<field name="ac_id" type="uint8_t"/>
|
||||
<field name="source_strength" type="int8_t" unit="dB"/>
|
||||
<field name="rssi" type="int8_t" unit="dB"/>
|
||||
</message>
|
||||
|
||||
</msg_class>
|
||||
|
||||
|
||||
@@ -159,13 +159,7 @@
|
||||
|
||||
<section name="INS" prefix="INS_">
|
||||
<define name="USE_GPS_ALT" value="1"/>
|
||||
</section>
|
||||
|
||||
<section name="GPS" prefix="GPS_">
|
||||
<define name="USE_DATALINK_SMALL" value="1"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_X" value="392433200"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_Y" value="30036200"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_Z" value="500219700"/>
|
||||
<define name="USE_GPS_ALT_SPEED" value="1"/>
|
||||
</section>
|
||||
|
||||
<section name="GUIDANCE_V" prefix="GUIDANCE_V_">
|
||||
@@ -183,8 +177,6 @@
|
||||
<define name="H_Z" value="0.92060036"/>
|
||||
<define name="USE_GPS_HEADING" value="1"/>
|
||||
</section>
|
||||
<define name="USE_GPS" value="TRUE"/>
|
||||
<define name="USE_GPS_HEADING" value="TRUE"/>
|
||||
|
||||
<section name="GUIDANCE_H" prefix="GUIDANCE_H_">
|
||||
<define name="PGAIN" value="290"/>
|
||||
|
||||
@@ -180,8 +180,8 @@
|
||||
</section>
|
||||
|
||||
<section name="SIMULATOR" prefix="NPS_">
|
||||
<define name="ACTUATOR_NAMES" value="ne_motor, se_motor, sw_motor, nw_motor" type="string[]"/>
|
||||
<define name="JSBSIM_MODEL" value="simple_x_quad" type="string"/>
|
||||
<define name="ACTUATOR_NAMES" value="nw_motor, ne_motor, se_motor, sw_motor" type="string[]"/>
|
||||
<define name="JSBSIM_MODEL" value="simple_x_quad_ccw" type="string"/>
|
||||
<define name="SENSORS_PARAMS" value="nps_sensors_params_default.h" type="string"/>
|
||||
<!-- mode switch on joystick channel 5 (axis numbering starting at zero) -->
|
||||
<define name="JS_AXIS_MODE" value="4"/>
|
||||
|
||||
@@ -173,13 +173,6 @@
|
||||
<define name="USE_GPS_ALT" value="1"/>
|
||||
</section>
|
||||
|
||||
<section name="GPS" prefix="GPS_">
|
||||
<define name="USE_DATALINK_SMALL" value="1"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_X" value="392433200"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_Y" value="30036200"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_Z" value="500219700"/>
|
||||
</section>
|
||||
|
||||
<section name="GUIDANCE_V" prefix="GUIDANCE_V_">
|
||||
<define name="HOVER_KP" value="276"/>
|
||||
<define name="HOVER_KD" value="455"/>
|
||||
|
||||
@@ -102,13 +102,6 @@
|
||||
<define name="SONAR_UPDATE_ON_AGL" value="TRUE"/>
|
||||
</section>
|
||||
|
||||
<section name="GPS" prefix="GPS_">
|
||||
<define name="USE_DATALINK_SMALL" value="1"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_X" value="392433200"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_Y" value="30036200"/>
|
||||
<define name="LOCAL_ECEF_ORIGIN_Z" value="500219700"/>
|
||||
</section>
|
||||
|
||||
<section name="STABILIZATION_RATE" prefix="STABILIZATION_RATE_">
|
||||
<!-- setpoints -->
|
||||
<define name="SP_MAX_P" value="140" unit="deg/s"/>
|
||||
|
||||
@@ -181,14 +181,14 @@
|
||||
<define name="H_X" value="0.39049610"/>
|
||||
<define name="H_Y" value="0.00278894"/>
|
||||
<define name="H_Z" value="0.92060036"/>
|
||||
<define name="USE_GPS_HEADING" value="1"/>
|
||||
<define name="USE_GPS_HEADING" value="0"/>
|
||||
</section>
|
||||
<define name="USE_GPS" value="FALSE"/>
|
||||
<define name="USE_GPS_HEADING" value="FALSE"/>
|
||||
|
||||
|
||||
|
||||
<section name="GUIDANCE_H" prefix="GUIDANCE_H_">
|
||||
<define name="PGAIN" value="40"/>
|
||||
<define name="DGAIN" value="10"/>
|
||||
<define name="PGAIN" value="120"/>
|
||||
<define name="DGAIN" value="40"/>
|
||||
<define name="IGAIN" value="0"/>
|
||||
<define name="REF_MAX_SPEED" value="0.5"/>
|
||||
<define name="USE_REF" value="FALSE"/>
|
||||
@@ -252,6 +252,8 @@
|
||||
<subsystem name="gps" type="datalink"/>
|
||||
<subsystem name="stabilization" type="int_quat"/>
|
||||
<subsystem name="ahrs" type="int_cmpl_quat"/>
|
||||
<subsystem name="ins" />
|
||||
<subsystem name="ins">
|
||||
<define name="INS_INT_GPS_ID" value="ABI_DISABLE"/>
|
||||
</subsystem>
|
||||
</firmware>
|
||||
</airframe>
|
||||
|
||||
@@ -16,9 +16,9 @@ $(TARGET).LDSCRIPT=$(SRC_ARCH)/naze32.ld
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# default flash mode is via SWD
|
||||
# default flash mode is via SERIAL (USB plug which is connected to cp210x converter)
|
||||
# other possibilities: DFU-UTIL, JTAG, SWD, STLINK, SERIAL
|
||||
FLASH_MODE ?= SWD
|
||||
FLASH_MODE ?= SERIAL
|
||||
|
||||
#
|
||||
#
|
||||
|
||||
@@ -16,9 +16,9 @@ $(TARGET).LDSCRIPT=$(SRC_ARCH)/naze32.ld
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# default flash mode is via SWD
|
||||
# default flash mode is via SERIAL (USB plug which is connected to cp210x converter)
|
||||
# other possibilities: DFU-UTIL, JTAG, SWD, STLINK, SERIAL
|
||||
FLASH_MODE ?= SWD
|
||||
FLASH_MODE ?= SERIAL
|
||||
|
||||
#
|
||||
#
|
||||
|
||||
@@ -1,27 +1,3 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
# UBlox LEA 4P
|
||||
include $(CFG_SHARED)/gps_ublox.makefile
|
||||
|
||||
GPS_LED ?= none
|
||||
UBX_GPS_PORT_LOWER=$(shell echo $(GPS_PORT) | tr A-Z a-z)
|
||||
|
||||
ap.CFLAGS += -DUSE_GPS -DUBX
|
||||
ap.CFLAGS += -DGPS_LINK=$(UBX_GPS_PORT_LOWER)
|
||||
ap.CFLAGS += -DUSE_$(GPS_PORT)
|
||||
ap.CFLAGS += -D$(GPS_PORT)_BAUD=$(GPS_BAUD)
|
||||
|
||||
ifneq ($(GPS_LED),none)
|
||||
ap.CFLAGS += -DGPS_LED=$(GPS_LED)
|
||||
endif
|
||||
|
||||
ap.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_ubx.h\"
|
||||
ap.srcs += $(SRC_SUBSYSTEMS)/gps/gps_ubx.c
|
||||
|
||||
$(TARGET).srcs += $(SRC_SUBSYSTEMS)/gps.c
|
||||
|
||||
sim.CFLAGS += -DUSE_GPS -DGPS_TYPE_H=\"subsystems/gps/gps_sim.h\"
|
||||
sim.srcs += $(SRC_SUBSYSTEMS)/gps/gps_sim.c
|
||||
|
||||
nps.CFLAGS += -DUSE_GPS
|
||||
nps.srcs += $(SRC_SUBSYSTEMS)/gps.c
|
||||
nps.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_sim_nps.h\"
|
||||
nps.srcs += $(SRC_SUBSYSTEMS)/gps/gps_sim_nps.c
|
||||
$(info Please replace <subsystem name="gps" type="ublox_utm"/> with <subsystem name="gps" type="ublox"/>)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
# UBlox LEA 5H
|
||||
# UBlox LEA
|
||||
|
||||
GPS_LED ?= none
|
||||
UBX_GPS_PORT_LOWER=$(shell echo $(GPS_PORT) | tr A-Z a-z)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#
|
||||
# Apogee IMU
|
||||
#
|
||||
|
||||
include $(CFG_SHARED)/imu_apogee.makefile
|
||||
|
||||
IMU_APOGEE_MPU9150_CFLAGS = -DAPOGEE_USE_MPU9150
|
||||
IMU_APOGEE_MPU9150_SRCS = peripherals/ak8975.c
|
||||
|
||||
# add it for all targets except sim, fbw and nps
|
||||
ifeq (,$(findstring $(TARGET),sim fbw nps))
|
||||
$(TARGET).CFLAGS += $(IMU_APOGEE_MPU9150_CFLAGS)
|
||||
$(TARGET).srcs += $(IMU_APOGEE_MPU9150_SRCS)
|
||||
endif
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<board name="lia_.*"/>
|
||||
<board name="lisa_[ms]_.*"/>
|
||||
<board name="elle*"/>
|
||||
<board name="naze32*"/>
|
||||
</boards>
|
||||
</mode>
|
||||
<mode name="USB (IAP)">
|
||||
|
||||
+3
-3
@@ -856,7 +856,6 @@
|
||||
|
||||
<message name="BLUEGIGA" id="106">
|
||||
<field name="data_rate" type="uint32" unit="bytes/s"/>
|
||||
<field name="last_msg" type="uint8[]"/>
|
||||
</message>
|
||||
|
||||
<!--107 is free -->
|
||||
@@ -2479,8 +2478,9 @@
|
||||
<message name="REMOTE_GPS_SMALL" id="54" link="broadcasted">
|
||||
<field name="ac_id" type="uint8"/>
|
||||
<field name="numsv" type="uint8"/>
|
||||
<field name="pos_xyz" type="uint32" unit="cm">bits 31-22 x position in cm : bits 21-12 y position in cm : bits 11-2 z position in cm : bits 1 and 0 are free</field>
|
||||
<field name="speed_xy" type="uint32" unit="cm/s">bits 31-22 speed x in cm/s : bits 21-12 speed y in cm/s : bits 11-2 heading in rad*1e2 : bits 1 and 0 are free</field>
|
||||
<field name="pos_xyz" type="uint32" unit="cm">bits 31-21 x position in cm : bits 20-10 y position in cm : bits 9-0 z position in cm</field>
|
||||
<field name="speed_xyz" type="uint32" unit="cm/s">bits 31-21 speed x in cm/s : bits 20-10 speed y in cm/s : bits 9-0 speed z in cm/s</field>
|
||||
<field name="heading" type="int16" unit="rad*1e4"/>
|
||||
</message>
|
||||
|
||||
<message name="REMOTE_GPS" id="55" link="broadcasted">
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<define name="AIRSPEED_ETS_SYNC_SEND" description="flag to transmit the data as it is acquired"/>
|
||||
<define name="USE_AIRSPEED_ETS" value="TRUE|FALSE" description="set airspeed in state interface"/>
|
||||
<define name="AIRSPEED_ETS_3RD_PARTY_MODE" description="read raw value for sensor in third-party mode"/>
|
||||
<define name="AIRSPEED_ETS_SDLOG" value="TRUE|FALSE" description="start logging to SD card"/>
|
||||
</doc>
|
||||
|
||||
<header>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</description>
|
||||
<define name="SHT_DAT_GPIO" value="port,pin" description="data GPIO (e.g.: GPIOA,GPIO8)"/>
|
||||
<define name="SHT_SCK_GPIO" value="port,pin" description="clock GPIO (e.g.: GPIOA,GPIO9)"/>
|
||||
<define name="SHT_SDLOG" value="TRUE|FALSE" description="start logging to SD card"/>
|
||||
</doc>
|
||||
<header>
|
||||
<file name="humid_sht.h"/>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<description>Hygrosens TEMOD-I2C-Rx temperature sensor</description>
|
||||
<configure name="TEMOD_I2C_DEV" value="i2cX" description="select i2c peripheral to use (default i2c0)"/>
|
||||
<define name="TEMOD_TYPE" value="type" description="device type (default TEMOD_I2C_R1)"/>
|
||||
<define name="TEMOD_SDLOG" value="TRUE|FALSE" description="start logging to SD card"/>
|
||||
</doc>
|
||||
<header>
|
||||
<file name="temp_temod.h"/>
|
||||
@@ -14,12 +15,12 @@
|
||||
<event fun="temod_event()"/>
|
||||
<makefile target="ap">
|
||||
<raw>
|
||||
TEMOD_DEV ?= i2c0
|
||||
TEMOD_DEV_LOWER=$(shell echo $(TEMOD_DEV) | tr A-Z a-z)
|
||||
TEMOD_DEV_UPPER=$(shell echo $(TEMOD_DEV) | tr a-z A-Z)
|
||||
TEMOD_I2C_DEV ?= i2c0
|
||||
TEMOD_I2C_DEV_LOWER=$(shell echo $(TEMOD_I2C_DEV) | tr A-Z a-z)
|
||||
TEMOD_I2C_DEV_UPPER=$(shell echo $(TEMOD_I2C_DEV) | tr a-z A-Z)
|
||||
</raw>
|
||||
<define name="USE_$(TEMOD_DEV_UPPER)"/>
|
||||
<define name="TEMOD_DEV" value="$(TEMOD_DEV_LOWER)"/>
|
||||
<define name="USE_$(TEMOD_I2C_DEV_UPPER)"/>
|
||||
<define name="TEMOD_I2C_DEV" value="$(TEMOD_I2C_DEV_LOWER)"/>
|
||||
<file name="temp_temod.c"/>
|
||||
</makefile>
|
||||
</module>
|
||||
|
||||
@@ -39,7 +39,7 @@ value sim_use_gps_pos(value x, value y, value z, value c, value a, value s, valu
|
||||
//TODO set alt above ellipsoid, use hmsl for now
|
||||
lla_f.alt = Double_val(a);
|
||||
LLA_BFP_OF_REAL(gps.lla_pos, lla_f);
|
||||
SetBit(gps.valid_fields, GPS_VALID_POS_UTM_BIT);
|
||||
SetBit(gps.valid_fields, GPS_VALID_POS_LLA_BIT);
|
||||
|
||||
gps.utm_pos.east = Int_val(x);
|
||||
gps.utm_pos.north = Int_val(y);
|
||||
|
||||
@@ -66,11 +66,33 @@ PRINT_CONFIG_VAR(APOGEE_GYRO_RANGE)
|
||||
#endif
|
||||
PRINT_CONFIG_VAR(APOGEE_ACCEL_RANGE)
|
||||
|
||||
#if APOGEE_USE_MPU9150
|
||||
/** Normal frequency with the default settings
|
||||
*
|
||||
* the mag read function should be called at around 50 Hz
|
||||
*/
|
||||
#ifndef APOGEE_MAG_FREQ
|
||||
#define APOGEE_MAG_FREQ 50
|
||||
#endif
|
||||
PRINT_CONFIG_VAR(APOGEE_MAG_FREQ)
|
||||
/** Mag periodic prescaler
|
||||
*/
|
||||
#define MAG_PRESCALER Max(1,((PERIODIC_FREQUENCY)/APOGEE_MAG_FREQ))
|
||||
PRINT_CONFIG_VAR(MAG_PRESCALER)
|
||||
|
||||
// mag config will be done later in bypass mode
|
||||
bool_t configure_mag_slave(Mpu60x0ConfigSet mpu_set, void *mpu);
|
||||
bool_t configure_mag_slave(Mpu60x0ConfigSet mpu_set __attribute__((unused)), void *mpu __attribute__((unused)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct ImuApogee imu_apogee;
|
||||
|
||||
// baro config will be done later in bypass mode
|
||||
bool_t configure_baro_slave(Mpu60x0ConfigSet mpu_set, void *mpu);
|
||||
|
||||
bool_t configure_baro_slave(Mpu60x0ConfigSet mpu_set __attribute__((unused)), void *mpu __attribute__((unused)))
|
||||
{
|
||||
return TRUE;
|
||||
@@ -90,6 +112,12 @@ void imu_impl_init(void)
|
||||
imu_apogee.mpu.config.nb_slaves = 1;
|
||||
imu_apogee.mpu.config.slaves[0].configure = &configure_baro_slave;
|
||||
imu_apogee.mpu.config.i2c_bypass = TRUE;
|
||||
#if APOGEE_USE_MPU9150
|
||||
// if using MPU9150, internal mag needs to be configured
|
||||
ak8975_init(&imu_apogee.ak, &(IMU_APOGEE_I2C_DEV), AK8975_I2C_SLV_ADDR);
|
||||
imu_apogee.mpu.config.nb_slaves = 2;
|
||||
imu_apogee.mpu.config.slaves[1].configure = &configure_mag_slave;
|
||||
#endif
|
||||
}
|
||||
|
||||
void imu_periodic(void)
|
||||
@@ -97,6 +125,11 @@ void imu_periodic(void)
|
||||
// Start reading the latest gyroscope data
|
||||
mpu60x0_i2c_periodic(&imu_apogee.mpu);
|
||||
|
||||
#if APOGEE_USE_MPU9150
|
||||
// Start reading internal mag if available
|
||||
RunOnceEvery(MAG_PRESCALER, ak8975_periodic(&imu_apogee.ak));
|
||||
#endif
|
||||
|
||||
//RunOnceEvery(10,imu_apogee_downlink_raw());
|
||||
}
|
||||
|
||||
@@ -134,5 +167,20 @@ void imu_apogee_event(void)
|
||||
AbiSendMsgIMU_GYRO_INT32(IMU_BOARD_ID, now_ts, &imu.gyro);
|
||||
AbiSendMsgIMU_ACCEL_INT32(IMU_BOARD_ID, now_ts, &imu.accel);
|
||||
}
|
||||
|
||||
#if APOGEE_USE_MPU9150
|
||||
ak8975_event(&imu_apogee.ak);
|
||||
if (imu_apogee.ak.data_available) {
|
||||
struct Int32Vect3 mag = {
|
||||
(int32_t)( imu_apogee.ak.data.value[IMU_APOGEE_CHAN_Y]),
|
||||
(int32_t)(-imu_apogee.ak.data.value[IMU_APOGEE_CHAN_X]),
|
||||
(int32_t)( imu_apogee.ak.data.value[IMU_APOGEE_CHAN_Z])
|
||||
};
|
||||
VECT3_COPY(imu.mag_unscaled, mag);
|
||||
imu_apogee.ak.data_available = FALSE;
|
||||
imu_scale_mag(&imu);
|
||||
AbiSendMsgIMU_MAG_INT32(IMU_BOARD_ID, now_ts, &imu.mag);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#include "std.h"
|
||||
#include "generated/airframe.h"
|
||||
#include "subsystems/imu.h"
|
||||
#if APOGEE_USE_MPU9150
|
||||
#include "peripherals/ak8975.h"
|
||||
#endif
|
||||
|
||||
#include "peripherals/mpu60x0_i2c.h"
|
||||
|
||||
@@ -96,6 +99,9 @@
|
||||
|
||||
struct ImuApogee {
|
||||
struct Mpu60x0_I2c mpu;
|
||||
#if APOGEE_USE_MPU9150
|
||||
struct Ak8975 ak;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct ImuApogee imu_apogee;
|
||||
|
||||
@@ -262,55 +262,42 @@
|
||||
* these directly map to the index number of the 4 adc channels defined above
|
||||
* 4th (index 3) is used for bat monitoring by default
|
||||
*/
|
||||
|
||||
#ifndef USE_ADC_1
|
||||
#define USE_ADC_1 1
|
||||
#endif
|
||||
|
||||
#if USE_ADC_1
|
||||
#define AD1_1_CHANNEL 13
|
||||
#define AD1_1_CHANNEL 14
|
||||
#define ADC_1 AD1_1
|
||||
#define ADC_1_GPIO_PORT GPIOC
|
||||
#define ADC_1_GPIO_PIN GPIO3
|
||||
#define ADC_1_GPIO_PIN GPIO4
|
||||
#endif
|
||||
|
||||
#if USE_ADC_2
|
||||
#define AD1_2_CHANNEL 10
|
||||
#define AD1_2_CHANNEL 15
|
||||
#define ADC_2 AD1_2
|
||||
#define ADC_2_GPIO_PORT GPIOC
|
||||
#define ADC_2_GPIO_PIN GPIO0
|
||||
#define ADC_2_GPIO_PIN GPIO5
|
||||
#endif
|
||||
|
||||
#if USE_ADC_3
|
||||
#define AD1_3_CHANNEL 11
|
||||
#define AD1_3_CHANNEL 0
|
||||
#define ADC_3 AD1_3
|
||||
#define ADC_3_GPIO_PORT GPIOC
|
||||
#define ADC_3_GPIO_PIN GPIO1
|
||||
#define ADC_3_GPIO_PORT GPIOA
|
||||
#define ADC_3_GPIO_PIN GPIO0
|
||||
#endif
|
||||
|
||||
#if USE_ADC_4
|
||||
#define AD2_1_CHANNEL 15
|
||||
#define ADC_4 AD2_1
|
||||
#define ADC_4_GPIO_PORT GPIOC
|
||||
#define ADC_4_GPIO_PIN GPIO5
|
||||
#endif
|
||||
|
||||
// Internal ADC for battery enabled by default
|
||||
#ifndef USE_ADC_5
|
||||
#define USE_ADC_5 1
|
||||
#endif
|
||||
#if USE_ADC_5
|
||||
#define AD1_4_CHANNEL 14
|
||||
#define ADC_5 AD1_4
|
||||
#define ADC_5_GPIO_PORT GPIOC
|
||||
#define ADC_5_GPIO_PIN GPIO4
|
||||
#endif
|
||||
|
||||
#if USE_ADC_6
|
||||
#define AD2_2_CHANNEL 12
|
||||
#define ADC_6 AD2_2
|
||||
#define ADC_6_GPIO_PORT GPIOC
|
||||
#define ADC_6_GPIO_PIN GPIO2
|
||||
#define AD1_4_CHANNEL 1
|
||||
#define ADC_4 AD1_4
|
||||
#define ADC_4_GPIO_PORT GPIOA
|
||||
#define ADC_4_GPIO_PIN GPIO1
|
||||
#endif
|
||||
|
||||
/* allow to define ADC_CHANNEL_VSUPPLY in the airframe file*/
|
||||
#ifndef ADC_CHANNEL_VSUPPLY
|
||||
#define ADC_CHANNEL_VSUPPLY ADC_5
|
||||
#define ADC_CHANNEL_VSUPPLY ADC_1
|
||||
#endif
|
||||
|
||||
#define DefaultVoltageOfAdc(adc) (0.0045*adc)
|
||||
|
||||
@@ -90,7 +90,7 @@ void dl_parse_msg(void)
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined USE_NAVIGATION
|
||||
#ifdef USE_NAVIGATION
|
||||
case DL_BLOCK : {
|
||||
if (DL_BLOCK_ac_id(dl_buffer) != AC_ID) { break; }
|
||||
nav_goto_block(DL_BLOCK_block_id(dl_buffer));
|
||||
@@ -138,21 +138,21 @@ void dl_parse_msg(void)
|
||||
}
|
||||
break;
|
||||
#endif // RADIO_CONTROL_TYPE_DATALINK
|
||||
#if defined GPS_DATALINK
|
||||
#ifdef GPS_USE_DATALINK_SMALL
|
||||
case DL_REMOTE_GPS_SMALL :
|
||||
#if USE_GPS
|
||||
#ifdef GPS_DATALINK
|
||||
case DL_REMOTE_GPS_SMALL : {
|
||||
// Check if the GPS is for this AC
|
||||
if (DL_REMOTE_GPS_SMALL_ac_id(dl_buffer) != AC_ID) {
|
||||
break;
|
||||
}
|
||||
if (DL_REMOTE_GPS_SMALL_ac_id(dl_buffer) != AC_ID) { break; }
|
||||
|
||||
parse_gps_datalink_small(
|
||||
DL_REMOTE_GPS_SMALL_numsv(dl_buffer),
|
||||
DL_REMOTE_GPS_SMALL_pos_xyz(dl_buffer),
|
||||
DL_REMOTE_GPS_SMALL_speed_xy(dl_buffer));
|
||||
break;
|
||||
#endif
|
||||
case DL_REMOTE_GPS :
|
||||
DL_REMOTE_GPS_SMALL_speed_xyz(dl_buffer),
|
||||
DL_REMOTE_GPS_SMALL_heading(dl_buffer));
|
||||
}
|
||||
break;
|
||||
|
||||
case DL_REMOTE_GPS : {
|
||||
// Check if the GPS is for this AC
|
||||
if (DL_REMOTE_GPS_ac_id(dl_buffer) != AC_ID) { break; }
|
||||
|
||||
@@ -171,10 +171,11 @@ void dl_parse_msg(void)
|
||||
DL_REMOTE_GPS_ecef_zd(dl_buffer),
|
||||
DL_REMOTE_GPS_tow(dl_buffer),
|
||||
DL_REMOTE_GPS_course(dl_buffer));
|
||||
break;
|
||||
#endif
|
||||
#if USE_GPS
|
||||
case DL_GPS_INJECT :
|
||||
}
|
||||
break;
|
||||
#endif // GPS_DATALINK
|
||||
|
||||
case DL_GPS_INJECT : {
|
||||
// Check if the GPS is for this AC
|
||||
if (DL_GPS_INJECT_ac_id(dl_buffer) != AC_ID) { break; }
|
||||
|
||||
@@ -183,9 +184,10 @@ void dl_parse_msg(void)
|
||||
DL_GPS_INJECT_packet_id(dl_buffer),
|
||||
DL_GPS_INJECT_data_length(dl_buffer),
|
||||
DL_GPS_INJECT_data(dl_buffer)
|
||||
);
|
||||
break;
|
||||
#endif
|
||||
);
|
||||
}
|
||||
break;
|
||||
#endif // USE_GPS
|
||||
|
||||
case DL_GUIDED_SETPOINT_NED:
|
||||
if (DL_GUIDED_SETPOINT_NED_ac_id(dl_buffer) != AC_ID) { break; }
|
||||
|
||||
@@ -408,7 +408,7 @@ void vPoint(float fPlaneEast, float fPlaneNorth, float fPlaneAltitude,
|
||||
struct UtmCoor_f utm;
|
||||
utm.east = nav_utm_east0 + fObjectEast;
|
||||
utm.north = nav_utm_north0 + fObjectNorth;
|
||||
utm.zone = gps.utm_pos.zone;
|
||||
utm.zone = nav_utm_zone0;
|
||||
struct LlaCoor_f lla;
|
||||
lla_of_utm_f(&lla, &utm);
|
||||
cam_point_lon = lla.lon * (180 / M_PI);
|
||||
|
||||
@@ -275,10 +275,7 @@ void ins_xsens_register(void)
|
||||
|
||||
void ins_xsens_update_gps(struct GpsState *gps_s)
|
||||
{
|
||||
struct UtmCoor_f utm;
|
||||
utm.east = gps_s->utm_pos.east / 100.;
|
||||
utm.north = gps_s->utm_pos.north / 100.;
|
||||
utm.zone = nav_utm_zone0;
|
||||
struct UtmCoor_f utm = utm_float_from_gps(gps_s, nav_utm_zone0);
|
||||
utm.alt = gps_s->hmsl / 1000.;
|
||||
|
||||
// set position
|
||||
|
||||
@@ -206,10 +206,7 @@ void ins_xsens_register(void)
|
||||
|
||||
void ins_xsens_update_gps(struct GpsState *gps_s)
|
||||
{
|
||||
struct UtmCoor_f utm;
|
||||
utm.east = gps_s->utm_pos.east / 100.;
|
||||
utm.north = gps_s->utm_pos.north / 100.;
|
||||
utm.zone = nav_utm_zone0;
|
||||
struct UtmCoor_f utm = utm_float_from_gps(gps_s, nav_utm_zone0);
|
||||
utm.alt = gps_s->hmsl / 1000.;
|
||||
|
||||
// set position
|
||||
|
||||
@@ -35,6 +35,14 @@
|
||||
#include "subsystems/datalink/downlink.h"
|
||||
#include "humid_sht.h"
|
||||
|
||||
// sd-log
|
||||
#if SHT_SDLOG
|
||||
#include "sdLog.h"
|
||||
#include "subsystems/chibios-libopencm3/chibios_sdlog.h"
|
||||
#include "subsystems/gps.h"
|
||||
bool_t log_sht_started;
|
||||
#endif
|
||||
|
||||
//#include "led.h"
|
||||
|
||||
#define noACK 0
|
||||
@@ -299,6 +307,11 @@ void humid_sht_init(void)
|
||||
|
||||
humid_sht_available = FALSE;
|
||||
humid_sht_status = SHT_IDLE;
|
||||
|
||||
#if SHT_SDLOG
|
||||
log_sht_started = FALSE;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void humid_sht_periodic(void)
|
||||
@@ -338,6 +351,21 @@ void humid_sht_periodic(void)
|
||||
humid_sht_status = SHT_MEASURING_HUMID;
|
||||
DOWNLINK_SEND_SHT_STATUS(DefaultChannel, DefaultDevice, &humidsht, &tempsht, &fhumidsht, &ftempsht);
|
||||
humid_sht_available = FALSE;
|
||||
|
||||
#if SHT_SDLOG
|
||||
if (pprzLogFile != -1) {
|
||||
if (!log_sht_started) {
|
||||
sdLogWriteLog(pprzLogFile, "SHT75: Humid(pct) Temp(degC) H(usec) GPS_fix TOW(ms) Week Lat(1e7rad) Lon(1e7rad) HMSL(mm) gpseed(cm/s) course(1e7rad) climb(cm/s)\n");
|
||||
log_sht_started = TRUE;
|
||||
}
|
||||
sdLogWriteLog(pprzLogFile, "sht75: %9.4f %9.4f %d %d %d %d %d %d %d %d %d\n",
|
||||
fhumidsht, ftempsht,
|
||||
gps.fix, gps.tow, gps.week,
|
||||
gps.lla_pos.lat, gps.lla_pos.lon, gps.hmsl,
|
||||
gps.gspeed, gps.course, -gps.ned_vel.z);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,10 +106,12 @@ void mf_daq_send_report(void)
|
||||
uint8_t foo = 0;
|
||||
int16_t climb = -gps.ned_vel.z;
|
||||
int16_t course = (DegOfRad(gps.course) / ((int32_t)1e6));
|
||||
struct UtmCoor_f utm = stateGetPositionEnu_f();
|
||||
int32_t east = utm.east * 100;
|
||||
int32_t north = utm.north * 100;
|
||||
DOWNLINK_SEND_GPS(pprzlog_tp, chibios_sdlog, &gps.fix,
|
||||
&gps.utm_pos.east, &gps.utm_pos.north,
|
||||
&course, &gps.hmsl, &gps.gspeed, &climb,
|
||||
&gps.week, &gps.tow, &gps.utm_pos.zone, &foo);
|
||||
&east, &north, &course, &gps.hmsl, &gps.gspeed, &climb,
|
||||
&gps.week, &gps.tow, &utm.zone, &foo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
#include "pprzlink/messages.h"
|
||||
#include "subsystems/datalink/downlink.h"
|
||||
|
||||
// sd-log
|
||||
#if TEMP_TEMOD_SDLOG
|
||||
#include "sdLog.h"
|
||||
#include "subsystems/chibios-libopencm3/chibios_sdlog.h"
|
||||
#include "subsystems/gps.h"
|
||||
bool_t log_temod_started;
|
||||
#endif
|
||||
|
||||
float ftmd_temperature;
|
||||
struct i2c_transaction tmd_trans;
|
||||
|
||||
@@ -50,11 +58,16 @@ struct i2c_transaction tmd_trans;
|
||||
void temod_init(void)
|
||||
{
|
||||
tmd_trans.status = I2CTransDone;
|
||||
|
||||
#if TEMP_TEMOD_SDLOG
|
||||
log_temod_started = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void temod_periodic(void)
|
||||
{
|
||||
i2c_receive(&TEMOD_I2C_DEV, &tmd_trans, TEMOD_SLAVE_ADDR, 2);
|
||||
|
||||
}
|
||||
|
||||
void temod_event(void)
|
||||
@@ -72,6 +85,24 @@ void temod_event(void)
|
||||
|
||||
DOWNLINK_SEND_TMP_STATUS(DefaultChannel, DefaultDevice, &tmd_temperature, &ftmd_temperature);
|
||||
tmd_trans.status = I2CTransDone;
|
||||
|
||||
|
||||
#if TEMP_TEMOD_SDLOG
|
||||
if (pprzLogFile != -1) {
|
||||
if (!log_temod_started) {
|
||||
sdLogWriteLog(pprzLogFile, "TEMOD: Temp(degC) H(usec) GPS_fix TOW(ms) Week Lat(1e7rad) Lon(1e7rad) HMSL(mm) gpseed(cm/s) course(1e7rad) climb(cm/s)\n");
|
||||
log_temod_started = TRUE;
|
||||
}
|
||||
else {
|
||||
sdLogWriteLog(pprzLogFile, "temod: %9.4f %d %d %d %d %d %d %d %d %d\n",
|
||||
ftmd_temperature,
|
||||
gps.fix, gps.tow, gps.week,
|
||||
gps.lla_pos.lat, gps.lla_pos.lon, gps.hmsl,
|
||||
gps.gspeed, gps.course, -gps.ned_vel.z);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,13 @@ PRINT_CONFIG_VAR(AIRSPEED_ETS_I2C_DEV)
|
||||
#endif
|
||||
PRINT_CONFIG_VAR(AIRSPEED_ETS_START_DELAY)
|
||||
|
||||
#if AIRSPEED_ETS_SDLOG
|
||||
#include "sdLog.h"
|
||||
#include "subsystems/chibios-libopencm3/chibios_sdlog.h"
|
||||
#include "subsystems/gps.h"
|
||||
bool_t log_airspeed_ets_started;
|
||||
#endif
|
||||
|
||||
|
||||
// Global variables
|
||||
uint16_t airspeed_ets_raw;
|
||||
@@ -123,6 +130,10 @@ void airspeed_ets_init(void)
|
||||
|
||||
airspeed_ets_delay_done = FALSE;
|
||||
SysTimeTimerStart(airspeed_ets_delay_time);
|
||||
|
||||
#if AIRSPEED_ETS_SDLOG
|
||||
log_airspeed_ets_started = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void airspeed_ets_read_periodic(void)
|
||||
@@ -221,6 +232,23 @@ void airspeed_ets_read_event(void)
|
||||
airspeed_ets = 0.0;
|
||||
}
|
||||
|
||||
|
||||
#if AIRSPEED_ETS_SDLOG
|
||||
if (pprzLogFile != -1) {
|
||||
if (!log_airspeed_ets_started) {
|
||||
sdLogWriteLog(pprzLogFile, "AIRSPEED_ETS: raw offset airspeed(m/s) GPS_fix TOW(ms) Week Lat(1e7rad) Lon(1e7rad) HMSL(mm) gpseed(cm/s) course(1e7rad) climb(cm/s)\n");
|
||||
log_airspeed_ets_started = TRUE;
|
||||
}
|
||||
sdLogWriteLog(pprzLogFile, "airspeed_ets: %d %d %8.4f %d %d %d %d %d %d %d %d %d\n",
|
||||
airspeed_ets_raw, airspeed_ets_offset, airspeed_ets,
|
||||
gps.fix, gps.tow, gps.week,
|
||||
gps.lla_pos.lat, gps.lla_pos.lon, gps.hmsl,
|
||||
gps.gspeed, gps.course, -gps.ned_vel.z);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Transaction has been read
|
||||
airspeed_ets_i2c_trans.status = I2CTransDone;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Xavier Paris, Gautier Hattenberger
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file peripherals/ak8975.c
|
||||
*
|
||||
* Driver for the AKM AK8975 magnetometer.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "peripherals/ak8975.h"
|
||||
#include "mcu_periph/sys_time.h"
|
||||
|
||||
#define AK8975_MEAS_TIME_MS 9
|
||||
|
||||
// Internal calibration coeff
|
||||
// Currently fetched at startup but not used after
|
||||
// Only relying on general IMU mag calibration
|
||||
static float calibration_values[3] = { 0, 0, 0 };
|
||||
|
||||
static float __attribute__((unused)) get_ajusted_value(const int16_t val, const uint8_t axis)
|
||||
{
|
||||
const float H = (float) val;
|
||||
const float corr_factor = calibration_values[axis];
|
||||
const float Hadj = corr_factor * H;
|
||||
|
||||
return Hadj;
|
||||
}
|
||||
|
||||
void ak8975_init(struct Ak8975 *ak, struct i2c_periph *i2c_p, uint8_t addr)
|
||||
{
|
||||
/* set i2c_peripheral */
|
||||
ak->i2c_p = i2c_p;
|
||||
/* set i2c address */
|
||||
ak->i2c_trans.slave_addr = addr;
|
||||
|
||||
ak->i2c_trans.status = I2CTransDone;
|
||||
|
||||
ak->initialized = FALSE;
|
||||
ak->status = AK_STATUS_IDLE;
|
||||
ak->init_status = AK_CONF_UNINIT;
|
||||
ak->data_available = FALSE;
|
||||
}
|
||||
|
||||
// Configure
|
||||
void ak8975_configure(struct Ak8975 *ak)
|
||||
{
|
||||
// Only configure when not busy
|
||||
if (ak->i2c_trans.status != I2CTransSuccess && ak->i2c_trans.status != I2CTransFailed
|
||||
&& ak->i2c_trans.status != I2CTransDone) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only when succesfull continue with next
|
||||
if (ak->i2c_trans.status == I2CTransSuccess) {
|
||||
ak->init_status++;
|
||||
}
|
||||
|
||||
ak->i2c_trans.status = I2CTransDone;
|
||||
switch (ak->init_status) {
|
||||
|
||||
case AK_CONF_UNINIT:
|
||||
// Set AK8975 in fuse ROM access mode to read ADC calibration data
|
||||
ak->i2c_trans.buf[0] = AK8975_REG_CNTL_ADDR;
|
||||
ak->i2c_trans.buf[1] = AK8975_MODE_FUSE_ACCESS;
|
||||
i2c_transmit(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 2);
|
||||
break;
|
||||
|
||||
case AK_REQ_CALIBRATION:
|
||||
// Request AK8975 for ADC calibration data
|
||||
ak->i2c_trans.buf[0] = AK8975_REG_ASASX;
|
||||
i2c_transceive(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 1, 3);
|
||||
break;
|
||||
|
||||
case AK_DISABLE_ACCESS_CALIBRATION:
|
||||
// Read config
|
||||
for (uint8_t i =0; i<=2; i++)
|
||||
calibration_values[i] =
|
||||
((((float)(ak->i2c_trans.buf[i]) - 128.0f)*0.5f)/128.0f)+1.0f;
|
||||
|
||||
// Set AK8975 in power-down mode to stop read calibration data
|
||||
ak->i2c_trans.buf[0] = AK8975_REG_CNTL_ADDR;
|
||||
ak->i2c_trans.buf[1] = AK8975_MODE_POWER_DOWN;
|
||||
i2c_transmit(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 2);
|
||||
break;
|
||||
|
||||
case AK_CONF_REQUESTED:
|
||||
ak->initialized = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ak8975_read(struct Ak8975 *ak)
|
||||
{
|
||||
if (ak->status != AK_STATUS_IDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send single measurement request
|
||||
ak->i2c_trans.buf[0] = AK8975_REG_CNTL_ADDR;
|
||||
ak->i2c_trans.buf[1] = AK8975_MODE_SINGLE_MEAS;
|
||||
i2c_transmit(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 2);
|
||||
ak->last_meas_time = get_sys_time_msec();
|
||||
ak->status = AK_STATUS_MEAS;
|
||||
}
|
||||
|
||||
// Get raw value
|
||||
#define RawFromBuf(_buf,_idx) ((int16_t)(_buf[_idx] | (_buf[_idx+1] << 8)))
|
||||
// Raw is actually a 14 bits signed value
|
||||
#define Int16FromRaw(_raw) ( (_raw & 0x1FFF) > 0xFFF ? (_raw & 0x1FFF) - 0x2000 : (_raw & 0x0FFF) )
|
||||
void ak8975_event(struct Ak8975 *ak)
|
||||
{
|
||||
if (!ak->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ak->status) {
|
||||
|
||||
case AK_STATUS_MEAS:
|
||||
// Send a read data command if measurement time is done (9ms max)
|
||||
if (ak->i2c_trans.status == I2CTransSuccess &&
|
||||
(get_sys_time_msec() - ak->last_meas_time >= AK8975_MEAS_TIME_MS)) {
|
||||
ak->i2c_trans.buf[0] = AK8975_REG_ST1_ADDR;
|
||||
i2c_transceive(ak->i2c_p, &(ak->i2c_trans), ak->i2c_trans.slave_addr, 1, 8);
|
||||
ak->status++;
|
||||
}
|
||||
break;
|
||||
|
||||
case AK_STATUS_READ:
|
||||
if (ak->i2c_trans.status == I2CTransSuccess) {
|
||||
// Mag data :
|
||||
// Status 1
|
||||
// 1 byte
|
||||
// Measures :
|
||||
// 2 bytes
|
||||
// 2 bytes
|
||||
// 2 bytes
|
||||
// Status 2
|
||||
// 1 byte
|
||||
|
||||
// Read status and error bytes
|
||||
const bool_t dr = ak->i2c_trans.buf[0] & 0x01; // data ready
|
||||
const bool_t de = ak->i2c_trans.buf[7] & 0x04; // data error
|
||||
const bool_t mo = ak->i2c_trans.buf[7] & 0x08; // mag overflow
|
||||
if (de || !dr) {
|
||||
// read error or data not ready, keep reading
|
||||
break;
|
||||
}
|
||||
if (mo) {
|
||||
// overflow, back to idle
|
||||
ak->status = AK_STATUS_IDLE;
|
||||
}
|
||||
// Copy the data
|
||||
int16_t val;
|
||||
val = RawFromBuf(ak->i2c_trans.buf, 1);
|
||||
ak->data.vect.x = Int16FromRaw(val);
|
||||
val = RawFromBuf(ak->i2c_trans.buf, 3);
|
||||
ak->data.vect.y = Int16FromRaw(val);
|
||||
val = RawFromBuf(ak->i2c_trans.buf, 5);
|
||||
ak->data.vect.z = Int16FromRaw(val);
|
||||
ak->data_available = TRUE;
|
||||
// End reading, back to idle
|
||||
ak->status = AK_STATUS_IDLE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ak->i2c_trans.status == I2CTransSuccess || ak->i2c_trans.status == I2CTransFailed) {
|
||||
// Goto idle
|
||||
ak->i2c_trans.status = I2CTransDone;
|
||||
ak->status = AK_STATUS_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Xavier Paris, Gautier Hattenberger
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file peripherals/ak8975.h
|
||||
*
|
||||
* Driver for the AKM AK8975 magnetometer.
|
||||
*/
|
||||
|
||||
#ifndef AK8975_H
|
||||
#define AK8975_H
|
||||
|
||||
#include "std.h"
|
||||
#include "mcu_periph/i2c.h"
|
||||
#include "math/pprz_algebra_int.h"
|
||||
|
||||
/* Address and register definitions */
|
||||
#define AK8975_I2C_SLV_ADDR (0x0C<<1)
|
||||
#define AK8975_REG_ST1_ADDR 0x02
|
||||
#define AK8975_REG_CNTL_ADDR 0x0A
|
||||
#define AK8975_REG_ASASX 0x10
|
||||
#define AK8975_MODE_FUSE_ACCESS 0b00001111
|
||||
#define AK8975_MODE_POWER_DOWN 0b00000000
|
||||
#define AK8975_MODE_SINGLE_MEAS 0b00000001
|
||||
|
||||
/** config status states */
|
||||
enum Ak8975ConfStatus {
|
||||
AK_CONF_UNINIT,
|
||||
AK_REQ_CALIBRATION,
|
||||
AK_DISABLE_ACCESS_CALIBRATION,
|
||||
AK_CONF_REQUESTED
|
||||
};
|
||||
|
||||
/** Normal status states */
|
||||
enum Ak8975Status {
|
||||
AK_STATUS_IDLE,
|
||||
AK_STATUS_MEAS,
|
||||
AK_STATUS_READ,
|
||||
AK_STATUS_DONE
|
||||
};
|
||||
|
||||
struct Ak8975 {
|
||||
struct i2c_periph *i2c_p; ///< peripheral used for communcation
|
||||
struct i2c_transaction i2c_trans; ///< i2c transaction used for communication with the ak8936
|
||||
bool_t initialized; ///< config done flag
|
||||
|
||||
enum Ak8975Status status; ///< main status
|
||||
enum Ak8975ConfStatus init_status; ///< init status
|
||||
uint32_t last_meas_time; ///< last measurement time in ms
|
||||
|
||||
volatile bool_t data_available; ///< data ready flag
|
||||
union {
|
||||
struct Int16Vect3 vect; ///< data vector in mag coordinate system
|
||||
int16_t value[3]; ///< data values accessible by channel index
|
||||
} data;
|
||||
};
|
||||
|
||||
|
||||
// Functions
|
||||
extern void ak8975_init(struct Ak8975 *ak, struct i2c_periph *i2c_p, uint8_t addr);
|
||||
extern void ak8975_configure(struct Ak8975 *ak);
|
||||
extern void ak8975_event(struct Ak8975 *ak);
|
||||
extern void ak8975_read(struct Ak8975 *ak);
|
||||
|
||||
/// convenience function: read or start configuration if not already initialized
|
||||
static inline void ak8975_periodic(struct Ak8975 *ak)
|
||||
{
|
||||
if (ak->initialized) {
|
||||
ak8975_read(ak);
|
||||
} else {
|
||||
ak8975_configure(ak);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AK8975_H */
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Felix Ruess <felix.ruess@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file peripherals/lsm303d_regs.h
|
||||
* Register defs for ST LSM303D 3D accelerometer and magnetometer.
|
||||
*
|
||||
* Has an I2C and SPI interface.
|
||||
* The LSM303D has linear acceleration full scales of ±2g / ±4g / ±6g / ±8g / ±16g
|
||||
* and a magnetic field full scale of ±2 / ±4 / ±8 / ±12 gauss.
|
||||
*/
|
||||
|
||||
#ifndef LSM303D_REGS_H
|
||||
#define LSM303D_REGS_H
|
||||
|
||||
/* Registers */
|
||||
#define LSM303D_REG_TEMP_OUT_L 0x05
|
||||
#define LSM303D_REG_TEMP_OUT_H 0x06
|
||||
#define LSM303D_REG_STATUS_M 0x07
|
||||
#define LSM303D_REG_OUT_X_L_M 0x08
|
||||
#define LSM303D_REG_OUT_X_H_M 0x09
|
||||
#define LSM303D_REG_OUT_Y_L_M 0x0A
|
||||
#define LSM303D_REG_OUT_Y_H_M 0x0B
|
||||
#define LSM303D_REG_OUT_Z_L_M 0x0C
|
||||
#define LSM303D_REG_OUT_Z_H_M 0x0D
|
||||
|
||||
#define LSM303D_REG_WHO_AM_I 0x0F
|
||||
|
||||
#define LSM303D_REG_INT_CTRL_M 0x12
|
||||
#define LSM303D_REG_INT_SRC_M 0x13
|
||||
#define LSM303D_REG_INT_THS_L_M 0x14
|
||||
#define LSM303D_REG_INT_THS_H_M 0x15
|
||||
#define LSM303D_REG_OFFSET_X_L_M 0x16
|
||||
#define LSM303D_REG_OFFSET_X_H_M 0x17
|
||||
#define LSM303D_REG_OFFSET_Y_L_M 0x18
|
||||
#define LSM303D_REG_OFFSET_Y_H_M 0x19
|
||||
#define LSM303D_REG_OFFSET_Z_L_M 0x1A
|
||||
#define LSM303D_REG_OFFSET_Z_H_M 0x1B
|
||||
#define LSM303D_REG_REFERENCE_X 0x1C
|
||||
#define LSM303D_REG_REFERENCE_Y 0x1D
|
||||
#define LSM303D_REG_REFERENCE_Z 0x1E
|
||||
#define LSM303D_REG_CTRL0 0x1F
|
||||
#define LSM303D_REG_CTRL1 0x20
|
||||
#define LSM303D_REG_CTRL2 0x21
|
||||
#define LSM303D_REG_CTRL3 0x22
|
||||
#define LSM303D_REG_CTRL4 0x23
|
||||
#define LSM303D_REG_CTRL5 0x24
|
||||
#define LSM303D_REG_CTRL6 0x25
|
||||
#define LSM303D_REG_CTRL7 0x26
|
||||
#define LSM303D_REG_STATUS_A 0x27
|
||||
#define LSM303D_REG_OUT_X_L_A 0x28
|
||||
#define LSM303D_REG_OUT_X_H_A 0x29
|
||||
#define LSM303D_REG_OUT_Y_L_A 0x2A
|
||||
#define LSM303D_REG_OUT_Y_H_A 0x2B
|
||||
#define LSM303D_REG_OUT_Z_L_A 0x2C
|
||||
#define LSM303D_REG_OUT_Z_H_A 0x2D
|
||||
#define LSM303D_REG_FIFO_CTRL 0x2E
|
||||
#define LSM303D_REG_FIFO_SRC 0x2F
|
||||
#define LSM303D_REG_IG_CFG1 0x30
|
||||
#define LSM303D_REG_IG_SRC1 0x31
|
||||
#define LSM303D_REG_IG_THS1 0x32
|
||||
#define LSM303D_REG_IG_DUR1 0x33
|
||||
#define LSM303D_REG_IG_CFG2 0x34
|
||||
#define LSM303D_REG_IG_SRC2 0x35
|
||||
#define LSM303D_REG_IG_THS2 0x36
|
||||
#define LSM303D_REG_IG_DUR2 0x37
|
||||
#define LSM303D_REG_CLICK_CFG 0x38
|
||||
#define LSM303D_REG_CLICK_SRC 0x39
|
||||
#define LSM303D_REG_CLICK_THS 0x3A
|
||||
#define LSM303D_REG_TIME_LIMIT 0x3B
|
||||
#define LSM303D_REG_TIME_LATENCY 0x3C
|
||||
#define LSM303D_REG_TIME_WINDOW 0x3D
|
||||
#define LSM303D_REG_ACT_THS 0x3E
|
||||
#define LSM303D_REG_ACT_DUR 0x3F
|
||||
|
||||
/** LSM303D device identifier in LSM303D_REG_WHO_AM_I */
|
||||
#define LSM303D_WHO_AM_I 0x49
|
||||
|
||||
/** LSM303D acceleration data rate (bits 4-7 in LSM303D_REG_CTRL1) */
|
||||
enum Lsm303dAccelRates {
|
||||
LSM303D_ACC_RATE_OFF = 0x0,
|
||||
LSM303D_ACC_RATE_3_125HZ = 0x1,
|
||||
LSM303D_ACC_RATE_6_25HZ = 0x2,
|
||||
LSM303D_ACC_RATE_12_5HZ = 0x3,
|
||||
LSM303D_ACC_RATE_25HZ = 0x4,
|
||||
LSM303D_ACC_RATE_50HZ = 0x5,
|
||||
LSM303D_ACC_RATE_100HZ = 0x6,
|
||||
LSM303D_ACC_RATE_200HZ = 0x7,
|
||||
LSM303D_ACC_RATE_400HZ = 0x8,
|
||||
LSM303D_ACC_RATE_800HZ = 0x9,
|
||||
LSM303D_ACC_RATE_1600HZ = 0xA
|
||||
};
|
||||
|
||||
/* Bit definitions for LSM303D_REG_CTRL1 */
|
||||
#define LSM303D_AXEN (1 << 0)
|
||||
#define LSM303D_AYEN (1 << 1)
|
||||
#define LSM303D_AZEN (1 << 3)
|
||||
|
||||
/** LSM303D accelerometer anti-alias filter bandwidth (bits 6-7 in LSM303D_REG_CTRL2) */
|
||||
enum Lsm303dAccelBandwidth {
|
||||
LSM303D_ACC_BW_773HZ = 0,
|
||||
LSM303D_ACC_BW_194HZ = 1,
|
||||
LSM303D_ACC_BW_362HZ = 2,
|
||||
LSM303D_ACC_BW_50HZ = 3
|
||||
};
|
||||
|
||||
/** LSM303D accelerometer anti-alias filter bandwidth (bits 3-5 in LSM303D_REG_CTRL2) */
|
||||
enum Lsm303dAccelRanges {
|
||||
LSM303D_ACC_RANGE_2G = 0x0,
|
||||
LSM303D_ACC_RANGE_4G = 0x1,
|
||||
LSM303D_ACC_RANGE_6G = 0x2,
|
||||
LSM303D_ACC_RANGE_8G = 0x3,
|
||||
LSM303D_ACC_RANGE_16G = 0x4
|
||||
};
|
||||
|
||||
/** LSM303D magnetic data rate (bits 2-4 in LSM303D_REG_CTRL5) */
|
||||
enum Lsm303dMagRates {
|
||||
LSM303D_MAG_RATE_3_125HZ = 0x0,
|
||||
LSM303D_MAG_RATE_6_25HZ = 0x1,
|
||||
LSM303D_MAG_RATE_12_5HZ = 0x2,
|
||||
LSM303D_MAG_RATE_25HZ = 0x3,
|
||||
LSM303D_MAG_RATE_50HZ = 0x4,
|
||||
LSM303D_MAG_RATE_100HZ = 0x5
|
||||
};
|
||||
|
||||
/** LSM303D magnetic range (bits 5-6 in LSM303D_REG_CTRL6) */
|
||||
enum Lsm303dMagRange {
|
||||
LSM303D_MAG_RANGE_2GAUSS = 0,
|
||||
LSM303D_MAG_RANGE_4GAUSS = 1,
|
||||
LSM303D_MAG_RANGE_8GAUSS = 2,
|
||||
LSM303D_MAG_RANGE_12GAUSS = 3,
|
||||
};
|
||||
|
||||
#endif // LSM303D_REGS_H
|
||||
@@ -44,6 +44,7 @@ void mpu60x0_set_default_config(struct Mpu60x0Config *c)
|
||||
*/
|
||||
c->nb_bytes = 15;
|
||||
c->nb_slaves = 0;
|
||||
c->nb_slave_init = 0;
|
||||
|
||||
c->i2c_bypass = FALSE;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,11 @@
|
||||
/// Default clock: PLL with X gyro reference
|
||||
#define MPU60X0_DEFAULT_CLK_SEL 1
|
||||
|
||||
// Default number of I2C slaves
|
||||
#ifndef MPU60X0_I2C_NB_SLAVES
|
||||
#define MPU60X0_I2C_NB_SLAVES 5
|
||||
#endif
|
||||
|
||||
enum Mpu60x0ConfStatus {
|
||||
MPU60X0_CONF_UNINIT,
|
||||
MPU60X0_CONF_RESET,
|
||||
@@ -87,7 +92,8 @@ struct Mpu60x0Config {
|
||||
bool_t i2c_bypass;
|
||||
|
||||
uint8_t nb_slaves; ///< number of used I2C slaves
|
||||
struct Mpu60x0I2cSlave slaves[5]; ///< I2C slaves
|
||||
uint8_t nb_slave_init; ///< number of already configured/initialized slaves
|
||||
struct Mpu60x0I2cSlave slaves[MPU60X0_I2C_NB_SLAVES]; ///< I2C slaves
|
||||
enum Mpu60x0MstClk i2c_mst_clk; ///< MPU I2C master clock speed
|
||||
uint8_t i2c_mst_delay; ///< MPU I2C slaves delayed sample rate
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ void mpu60x0_i2c_event(struct Mpu60x0_I2c *mpu)
|
||||
}
|
||||
}
|
||||
|
||||
/** @todo: only one slave so far. */
|
||||
/** configure the registered I2C slaves */
|
||||
bool_t mpu60x0_configure_i2c_slaves(Mpu60x0ConfigSet mpu_set, void *mpu)
|
||||
{
|
||||
struct Mpu60x0_I2c *mpu_i2c = (struct Mpu60x0_I2c *)(mpu);
|
||||
@@ -150,8 +150,15 @@ bool_t mpu60x0_configure_i2c_slaves(Mpu60x0ConfigSet mpu_set, void *mpu)
|
||||
mpu_i2c->slave_init_status++;
|
||||
break;
|
||||
case MPU60X0_I2C_CONF_SLAVES_CONFIGURE:
|
||||
/* configure each slave. TODO: currently only one */
|
||||
if (mpu_i2c->config.slaves[0].configure(mpu_set, mpu)) {
|
||||
/* configure each slave until all nb_slaves are done */
|
||||
if (mpu_i2c->config.nb_slave_init < mpu_i2c->config.nb_slaves && mpu_i2c->config.nb_slave_init < MPU60X0_I2C_NB_SLAVES) {
|
||||
// proceed to next slave if configure for current one returns true
|
||||
if (mpu_i2c->config.slaves[mpu_i2c->config.nb_slave_init].configure(mpu_set, mpu)) {
|
||||
mpu_i2c->config.nb_slave_init++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* all slave devies configured, continue MPU side configuration of I2C slave stuff */
|
||||
mpu_i2c->slave_init_status++;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -148,7 +148,7 @@ void mpu60x0_spi_event(struct Mpu60x0_Spi *mpu)
|
||||
}
|
||||
}
|
||||
|
||||
/** @todo: only one slave so far. */
|
||||
/** configure the registered I2C slaves */
|
||||
bool_t mpu60x0_configure_i2c_slaves(Mpu60x0ConfigSet mpu_set, void *mpu)
|
||||
{
|
||||
struct Mpu60x0_Spi *mpu_spi = (struct Mpu60x0_Spi *)(mpu);
|
||||
@@ -175,8 +175,15 @@ bool_t mpu60x0_configure_i2c_slaves(Mpu60x0ConfigSet mpu_set, void *mpu)
|
||||
mpu_spi->slave_init_status++;
|
||||
break;
|
||||
case MPU60X0_SPI_CONF_SLAVES_CONFIGURE:
|
||||
/* configure first slave, only one slave supported so far */
|
||||
if (mpu_spi->config.slaves[0].configure(mpu_set, mpu)) {
|
||||
/* configure each slave until all nb_slaves are done */
|
||||
if (mpu_spi->config.nb_slave_init < mpu_spi->config.nb_slaves && mpu_spi->config.nb_slave_init < MPU60X0_I2C_NB_SLAVES) {
|
||||
// proceed to next slave if configure for current one returns true
|
||||
if (mpu_spi->config.slaves[mpu_spi->config.nb_slave_init].configure(mpu_set, mpu)) {
|
||||
mpu_spi->config.nb_slave_init++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* all slave devies configured, continue MPU side configuration of I2C slave stuff */
|
||||
mpu_spi->slave_init_status++;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -45,6 +45,7 @@ void mpu9250_set_default_config(struct Mpu9250Config *c)
|
||||
*/
|
||||
c->nb_bytes = 15;
|
||||
c->nb_slaves = 0;
|
||||
c->nb_slave_init = 0;
|
||||
|
||||
c->i2c_bypass = FALSE;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
/// Default clock: PLL with X gyro reference
|
||||
#define MPU9250_DEFAULT_CLK_SEL 1
|
||||
|
||||
// Default number of I2C slaves
|
||||
#ifndef MPU9250_I2C_NB_SLAVES
|
||||
#define MPU9250_I2C_NB_SLAVES 5
|
||||
#endif
|
||||
|
||||
enum Mpu9250ConfStatus {
|
||||
MPU9250_CONF_UNINIT,
|
||||
MPU9250_CONF_RESET,
|
||||
@@ -90,7 +95,8 @@ struct Mpu9250Config {
|
||||
bool_t i2c_bypass;
|
||||
|
||||
uint8_t nb_slaves; ///< number of used I2C slaves
|
||||
struct Mpu9250I2cSlave slaves[5]; ///< I2C slaves
|
||||
uint8_t nb_slave_init; ///< number of already configured/initialized slaves
|
||||
struct Mpu9250I2cSlave slaves[MPU9250_I2C_NB_SLAVES]; ///< I2C slaves
|
||||
enum Mpu9250MstClk i2c_mst_clk; ///< MPU I2C master clock speed
|
||||
uint8_t i2c_mst_delay; ///< MPU I2C slaves delayed sample rate
|
||||
};
|
||||
|
||||
@@ -163,7 +163,7 @@ bool_t imu_mpu9250_configure_mag_slave(Mpu9250ConfigSet mpu_set __attribute__((u
|
||||
}
|
||||
}
|
||||
|
||||
/** @todo: only one slave so far. */
|
||||
/** configure the registered I2C slaves */
|
||||
bool_t mpu9250_configure_i2c_slaves(Mpu9250ConfigSet mpu_set, void *mpu)
|
||||
{
|
||||
struct Mpu9250_I2c *mpu_i2c = (struct Mpu9250_I2c *)(mpu);
|
||||
@@ -183,8 +183,15 @@ bool_t mpu9250_configure_i2c_slaves(Mpu9250ConfigSet mpu_set, void *mpu)
|
||||
mpu_i2c->slave_init_status++;
|
||||
break;
|
||||
case MPU9250_I2C_CONF_SLAVES_CONFIGURE:
|
||||
/* configure each slave. TODO: currently only one */
|
||||
if (mpu_i2c->config.slaves[0].configure(mpu_set, mpu)) {
|
||||
/* configure each slave until all nb_slaves are done */
|
||||
if (mpu_i2c->config.nb_slave_init < mpu_i2c->config.nb_slaves && mpu_i2c->config.nb_slave_init < MPU9250_I2C_NB_SLAVES) {
|
||||
// proceed to next slave if configure for current one returns true
|
||||
if (mpu_i2c->config.slaves[mpu_i2c->config.nb_slave_init].configure(mpu_set, mpu)) {
|
||||
mpu_i2c->config.nb_slave_init++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* all slave devies configured, continue MPU side configuration of I2C slave stuff */
|
||||
mpu_i2c->slave_init_status++;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -145,7 +145,7 @@ void mpu9250_spi_event(struct Mpu9250_Spi *mpu)
|
||||
}
|
||||
}
|
||||
|
||||
/** @todo: only one slave so far. */
|
||||
/** configure the registered I2C slaves */
|
||||
bool_t mpu9250_configure_i2c_slaves(Mpu9250ConfigSet mpu_set, void *mpu)
|
||||
{
|
||||
struct Mpu9250_Spi *mpu_spi = (struct Mpu9250_Spi *)(mpu);
|
||||
@@ -172,8 +172,15 @@ bool_t mpu9250_configure_i2c_slaves(Mpu9250ConfigSet mpu_set, void *mpu)
|
||||
mpu_spi->slave_init_status++;
|
||||
break;
|
||||
case MPU9250_SPI_CONF_SLAVES_CONFIGURE:
|
||||
/* configure first slave, only one slave supported so far */
|
||||
if (mpu_spi->config.slaves[0].configure(mpu_set, mpu)) {
|
||||
/* configure each slave until all nb_slaves are done */
|
||||
if (mpu_spi->config.nb_slave_init < mpu_spi->config.nb_slaves && mpu_spi->config.nb_slave_init < MPU9250_I2C_NB_SLAVES) {
|
||||
// proceed to next slave if configure for current one returns true
|
||||
if (mpu_spi->config.slaves[mpu_spi->config.nb_slave_init].configure(mpu_set, mpu)) {
|
||||
mpu_spi->config.nb_slave_init++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* all slave devies configured, continue MPU side configuration of I2C slave stuff */
|
||||
mpu_spi->slave_init_status++;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -230,5 +230,12 @@
|
||||
#define PX4FLOW_VELOCITY_ID 17
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IDs of RSSI measurements (message 13)
|
||||
*/
|
||||
#ifndef RSSI_BLUEGIGA_ID
|
||||
#define RSSI_BLUEGIGA_ID 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* ABI_SENDER_IDS_H */
|
||||
|
||||
@@ -30,9 +30,19 @@
|
||||
#include "mcu_periph/gpio.h"
|
||||
#include "mcu_periph/spi.h"
|
||||
|
||||
#ifdef MODEM_LED
|
||||
#include "led.h"
|
||||
#endif
|
||||
|
||||
#include "subsystems/abi.h"
|
||||
|
||||
// for memset
|
||||
#include <string.h>
|
||||
|
||||
//#include "subsystems/datalink/telemetry_common.h"
|
||||
//#include "subsystems/datalink/telemetry.h"
|
||||
#include "generated/periodic_telemetry.h"
|
||||
|
||||
#ifndef BLUEGIGA_SPI_DEV
|
||||
#error "bluegiga: must define a BLUEGIGA_SPI_DEV"
|
||||
#endif
|
||||
@@ -46,14 +56,18 @@
|
||||
#define BLUEGIGA_DRDY_GPIO_PIN SUPERBITRF_DRDY_PIN
|
||||
#endif
|
||||
|
||||
#define TxStrengthOfSender(x) (x[1])
|
||||
#define RssiOfSender(x) (x[2])
|
||||
#define Pprz_StxOfMsg(x) (x[3])
|
||||
#define SenderIdOfMsg(x) (x[5])
|
||||
|
||||
enum BlueGigaStatus coms_status;
|
||||
struct bluegiga_periph bluegiga_p;
|
||||
struct spi_transaction bluegiga_spi;
|
||||
|
||||
signed char bluegiga_rssi[256]; // values initialized with 127
|
||||
unsigned char telemetry_copy[20];
|
||||
uint8_t broadcast_msg[20];
|
||||
|
||||
void bluegiga_load_tx(struct bluegiga_periph *p);
|
||||
void bluegiga_load_tx(struct bluegiga_periph *p, struct spi_transaction *trans);
|
||||
void bluegiga_transmit(struct bluegiga_periph *p, uint8_t data);
|
||||
void bluegiga_receive(struct spi_transaction *trans);
|
||||
|
||||
@@ -80,6 +94,8 @@ static int dev_char_available(struct bluegiga_periph *p)
|
||||
{
|
||||
return bluegiga_ch_available(p);
|
||||
}
|
||||
|
||||
// note, need to run dev_char_available first
|
||||
static uint8_t dev_get_byte(struct bluegiga_periph *p)
|
||||
{
|
||||
uint8_t ret = p->rx_buf[p->rx_extract_idx];
|
||||
@@ -115,7 +131,7 @@ static void send_bluegiga(struct transport_tx *trans, struct link_device *dev)
|
||||
|
||||
if (now_ts > last_ts) {
|
||||
uint32_t rate = 1000 * bluegiga_p.bytes_recvd_since_last / (now_ts - last_ts);
|
||||
pprz_msg_send_BLUEGIGA(trans, dev, AC_ID, &rate, 20, telemetry_copy);
|
||||
pprz_msg_send_BLUEGIGA(trans, dev, AC_ID, &rate);
|
||||
|
||||
bluegiga_p.bytes_recvd_since_last = 0;
|
||||
last_ts = now_ts;
|
||||
@@ -140,7 +156,7 @@ void bluegiga_init(struct bluegiga_periph *p)
|
||||
bluegiga_spi.cpha = SPICphaEdge2;
|
||||
bluegiga_spi.dss = SPIDss8bit;
|
||||
bluegiga_spi.bitorder = SPIMSBFirst;
|
||||
bluegiga_spi.cdiv = SPIDiv64;
|
||||
bluegiga_spi.cdiv = SPIDiv256;
|
||||
bluegiga_spi.after_cb = (SPICallback) trans_cb;
|
||||
|
||||
// Configure generic link device
|
||||
@@ -157,18 +173,14 @@ void bluegiga_init(struct bluegiga_periph *p)
|
||||
p->tx_insert_idx = 0;
|
||||
p->tx_extract_idx = 0;
|
||||
|
||||
for (int i = 0; i < bluegiga_spi.input_length; i++) {
|
||||
p->work_rx[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < bluegiga_spi.output_length; i++) {
|
||||
p->work_tx[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 255; i++) {
|
||||
bluegiga_rssi[i] = 127;
|
||||
}
|
||||
memset(p->work_rx, 0, bluegiga_spi.input_length);
|
||||
memset(p->work_tx, 0, bluegiga_spi.output_length);
|
||||
|
||||
memset(broadcast_msg, 0, 19);
|
||||
|
||||
p->bytes_recvd_since_last = 0;
|
||||
p->end_of_msg = p->tx_insert_idx;
|
||||
p->connected = 0;
|
||||
|
||||
// set DRDY interrupt pin for spi master triggered on falling edge
|
||||
gpio_setup_output(BLUEGIGA_DRDY_GPIO, BLUEGIGA_DRDY_GPIO_PIN);
|
||||
@@ -194,10 +206,11 @@ void bluegiga_transmit(struct bluegiga_periph *p, uint8_t data)
|
||||
}
|
||||
|
||||
/* Load waiting data into tx peripheral buffer */
|
||||
void bluegiga_load_tx(struct bluegiga_periph *p)
|
||||
void bluegiga_load_tx(struct bluegiga_periph *p, struct spi_transaction *trans)
|
||||
{
|
||||
uint8_t packet_len;
|
||||
// check data available in buffer to send
|
||||
uint8_t packet_len = ((p->end_of_msg - p->tx_extract_idx + BLUEGIGA_BUFFER_SIZE) % BLUEGIGA_BUFFER_SIZE);
|
||||
packet_len = ((p->end_of_msg - p->tx_extract_idx + BLUEGIGA_BUFFER_SIZE) % BLUEGIGA_BUFFER_SIZE);
|
||||
if (packet_len > 19) {
|
||||
packet_len = 19;
|
||||
}
|
||||
@@ -214,7 +227,7 @@ void bluegiga_load_tx(struct bluegiga_periph *p)
|
||||
bluegiga_increment_buf(&p->tx_extract_idx, packet_len);
|
||||
|
||||
// clear unused bytes
|
||||
for (i = packet_len + 1; i < bluegiga_spi.output_length; i++) {
|
||||
for (i = packet_len + 1; i < trans->output_length; i++) {
|
||||
p->work_tx[i] = 0;
|
||||
}
|
||||
|
||||
@@ -235,97 +248,104 @@ void bluegiga_receive(struct spi_transaction *trans)
|
||||
for (uint8_t i = 0; i < trans->output_length; i++) {
|
||||
trans->output_buf[i] = 0;
|
||||
}
|
||||
} else if (coms_status == BLUEGIGA_SENDING_BROADCAST) {
|
||||
// sending second half of broadcast message
|
||||
for (uint8_t i = 0; i < broadcast_msg[0]; i++) {
|
||||
trans->output_buf[i] = broadcast_msg[i];
|
||||
}
|
||||
coms_status = BLUEGIGA_SENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 0xff communication lost with ground station
|
||||
* 0xfe RSSI value from broadcaster
|
||||
* 0xfd Change in broadcast mode
|
||||
* 0xfc Receive all recorded RSSI
|
||||
* <=20 Data package from ground station
|
||||
* >235 data package from broadcast mode
|
||||
* 0x50 communication lost with ground station
|
||||
* 0x51 interrupt handled
|
||||
* <20 data package from connection
|
||||
*/
|
||||
|
||||
uint8_t packet_len = 0;
|
||||
uint8_t read_offset = 0;
|
||||
switch (trans->input_buf[0]) {
|
||||
case 0xff: // communication lost with ground station
|
||||
#ifdef MODEM_LED
|
||||
LED_OFF(MODEM_LED);
|
||||
#endif
|
||||
coms_status = BLUEGIGA_UNINIT;
|
||||
gpio_set(BLUEGIGA_DRDY_GPIO, BLUEGIGA_DRDY_GPIO_PIN); // Reset interrupt pin
|
||||
break;
|
||||
case 0xfe: // RSSI value from broadcaster
|
||||
bluegiga_rssi[trans->input_buf[1]] = trans->input_buf[2];
|
||||
packet_len = trans->input_buf[3];
|
||||
read_offset = 4;
|
||||
break;
|
||||
case 0xfd: // Change in broadcast mode
|
||||
gpio_set(BLUEGIGA_DRDY_GPIO, BLUEGIGA_DRDY_GPIO_PIN); // Reset interrupt pin
|
||||
|
||||
// fetch scan status
|
||||
if (trans->input_buf[1] == 1) {
|
||||
coms_status = BLUEGIGA_BROADCASTING;
|
||||
case 0x50: // communication status changed
|
||||
bluegiga_p.connected = trans->input_buf[1];
|
||||
if (bluegiga_p.connected) {
|
||||
//telemetry_mode_Main = TELEMETRY_PROCESS_Main;
|
||||
} else {
|
||||
coms_status = BLUEGIGA_UNINIT;
|
||||
//telemetry_mode_Main = NB_TELEMETRY_MODES; // send no periodic telemetry
|
||||
}
|
||||
coms_status = BLUEGIGA_IDLE;
|
||||
break;
|
||||
case 0xfc: // Receive all recorded RSSI
|
||||
for (uint8_t i = 0; i < trans->input_buf[1]; i++) {
|
||||
bluegiga_rssi[trans->input_buf[2] + i] = trans->input_buf[3 + i];
|
||||
}
|
||||
case 0x51: // Interrupt handled
|
||||
gpio_set(BLUEGIGA_DRDY_GPIO, BLUEGIGA_DRDY_GPIO_PIN); // Reset interrupt pin
|
||||
break;
|
||||
default:
|
||||
packet_len = trans->input_buf[0]; // length of transmitted message
|
||||
read_offset = 1;
|
||||
coms_status = BLUEGIGA_IDLE;
|
||||
// compute length of transmitted message
|
||||
if (trans->input_buf[0] < trans->input_length) { // normal connection mode
|
||||
packet_len = trans->input_buf[0];
|
||||
read_offset = 1;
|
||||
} else if (trans->input_buf[0] > 0xff - trans->input_length) { // broadcast mode
|
||||
packet_len = 0xff - trans->input_buf[0];
|
||||
|
||||
int8_t tx_strength = TxStrengthOfSender(trans->input_buf);
|
||||
int8_t rssi = RssiOfSender(trans->input_buf);
|
||||
uint8_t ac_id = SenderIdOfMsg(trans->input_buf);
|
||||
|
||||
if (Pprz_StxOfMsg(trans->input_buf) == STX) {
|
||||
AbiSendMsgRSSI(RSSI_BLUEGIGA_ID, ac_id, tx_strength, rssi);
|
||||
}
|
||||
|
||||
read_offset = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// handle incoming datalink message
|
||||
if (packet_len > 0 && packet_len <= trans->input_length) {
|
||||
if (packet_len > 0 && packet_len <= trans->input_length - read_offset) {
|
||||
#ifdef MODEM_LED
|
||||
LED_TOGGLE(MODEM_LED);
|
||||
#endif
|
||||
// Handle received message
|
||||
for (uint8_t i = 0; i < packet_len; i++) {
|
||||
bluegiga_p.rx_buf[(bluegiga_p.rx_insert_idx + i) % BLUEGIGA_BUFFER_SIZE] = trans->input_buf[i + read_offset];
|
||||
}
|
||||
bluegiga_increment_buf(&bluegiga_p.rx_insert_idx, packet_len);
|
||||
bluegiga_p.bytes_recvd_since_last += packet_len;
|
||||
coms_status = BLUEGIGA_IDLE;
|
||||
|
||||
for (uint8_t i = 0; i < trans->input_length; i++) {
|
||||
telemetry_copy[i] = trans->input_buf[i];
|
||||
}
|
||||
} else {
|
||||
coms_status = BLUEGIGA_IDLE;
|
||||
}
|
||||
|
||||
// load next message to be sent into work buffer, needs to be loaded before calling spi_slave_register
|
||||
bluegiga_load_tx(&bluegiga_p);
|
||||
bluegiga_load_tx(&bluegiga_p, trans);
|
||||
|
||||
// register spi slave read for next transaction
|
||||
spi_slave_register(&(BLUEGIGA_SPI_DEV), &bluegiga_spi);
|
||||
spi_slave_register(&(BLUEGIGA_SPI_DEV), trans);
|
||||
}
|
||||
}
|
||||
|
||||
/* command bluetooth to switch to active scan mode to get rssi values from neighbouring drones */
|
||||
void bluegiga_scan(struct bluegiga_periph *p)
|
||||
/* Send data for broadcast message to the bluegiga module
|
||||
* maximum size of message is 22 bytes
|
||||
*/
|
||||
void bluegiga_broadcast_msg(struct bluegiga_periph *p, char *msg, uint8_t msg_len)
|
||||
{
|
||||
if (msg_len == 0 || msg_len > 22) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(p->work_tx, 0, 20);
|
||||
p->work_tx[0] = 0xfd; // change broadcast mode header
|
||||
uint8_t max_length = 20;
|
||||
p->work_tx[0] = msg_len;
|
||||
|
||||
coms_status = BLUEGIGA_SENDING;
|
||||
|
||||
// trigger bluegiga to read direct command
|
||||
gpio_clear(BLUEGIGA_DRDY_GPIO, BLUEGIGA_DRDY_GPIO_PIN); // set interrupt
|
||||
}
|
||||
|
||||
/* Request list of all recorded RSSI */
|
||||
void bluegiga_request_all_rssi(struct bluegiga_periph *p)
|
||||
{
|
||||
|
||||
memset(p->work_tx, 0, 20);
|
||||
p->work_tx[0] = 0xfc;
|
||||
|
||||
coms_status = BLUEGIGA_SENDING;
|
||||
if (msg_len < max_length) {
|
||||
for (uint8_t i = 0; i < msg_len; i++) {
|
||||
p->work_tx[i + 1] = msg[i];
|
||||
}
|
||||
coms_status = BLUEGIGA_SENDING;
|
||||
} else {
|
||||
for (uint8_t i = 0; i < max_length - 1; i++) {
|
||||
p->work_tx[i + 1] = msg[i];
|
||||
}
|
||||
|
||||
memcpy(broadcast_msg, msg + max_length - 1, msg_len - (max_length - 1));
|
||||
coms_status = BLUEGIGA_SENDING_BROADCAST;
|
||||
}
|
||||
|
||||
// trigger bluegiga to read direct command
|
||||
gpio_clear(BLUEGIGA_DRDY_GPIO, BLUEGIGA_DRDY_GPIO_PIN); // set interrupt
|
||||
|
||||
@@ -35,7 +35,7 @@ enum BlueGigaStatus {
|
||||
BLUEGIGA_UNINIT, /**< The com isn't initialized */
|
||||
BLUEGIGA_IDLE, /**< The com is in idle */
|
||||
BLUEGIGA_SENDING, /**< The com is sending */
|
||||
BLUEGIGA_BROADCASTING /**< The com is switched from data link to rssi scanning */
|
||||
BLUEGIGA_SENDING_BROADCAST /**< The com is switched from data link to rssi scanning */
|
||||
};
|
||||
|
||||
#ifndef BLUEGIGA_BUFFER_SIZE
|
||||
@@ -64,6 +64,7 @@ struct bluegiga_periph {
|
||||
/* some administrative variables */
|
||||
uint32_t bytes_recvd_since_last;
|
||||
uint8_t end_of_msg;
|
||||
uint8_t connected;
|
||||
|
||||
};
|
||||
|
||||
@@ -76,38 +77,6 @@ void bluegiga_increment_buf(uint8_t *buf_idx, uint8_t len);
|
||||
|
||||
void bluegiga_init(struct bluegiga_periph *p);
|
||||
void bluegiga_scan(struct bluegiga_periph *p);
|
||||
void bluegiga_request_all_rssi(struct bluegiga_periph *p);
|
||||
|
||||
// BLUEGIGA is using pprz_transport
|
||||
// FIXME it should not appear here, this will be fixed with the rx improvements some day...
|
||||
// BLUEGIGA needs a specific read_buffer function
|
||||
#include "pprzlink/pprz_transport.h"
|
||||
#include "led.h"
|
||||
static inline void bluegiga_read_buffer(struct bluegiga_periph *p, struct pprz_transport *t)
|
||||
{
|
||||
do {
|
||||
uint8_t c = 0;
|
||||
do {
|
||||
parse_pprz(t, p->rx_buf[(p->rx_extract_idx + c++) % BLUEGIGA_BUFFER_SIZE]);
|
||||
} while (((p->rx_extract_idx + c) % BLUEGIGA_BUFFER_SIZE != p->rx_insert_idx)
|
||||
&& !(t->trans_rx.msg_received));
|
||||
// reached end of circular read buffer or message received
|
||||
// if received, decode and advance
|
||||
if (t->trans_rx.msg_received) {
|
||||
#ifdef MODEM_LED
|
||||
LED_TOGGLE(MODEM_LED);
|
||||
#endif
|
||||
DatalinkFillDlBuffer(t->trans_rx.payload, t->trans_rx.payload_len);
|
||||
t->trans_rx.msg_received = FALSE;
|
||||
}
|
||||
bluegiga_increment_buf(&p->rx_extract_idx, c);
|
||||
} while (bluegiga_ch_available(p)); // continue till all messages read
|
||||
}
|
||||
|
||||
// transmit previous data in buffer and parse data received
|
||||
#define BlueGigaCheckAndParse(_dev,_trans) { \
|
||||
if (bluegiga_ch_available(&(_dev))) \
|
||||
bluegiga_read_buffer(&(_dev), &(_trans)); \
|
||||
}
|
||||
void bluegiga_broadcast_msg(struct bluegiga_periph *p, char *msg, uint8_t msg_len);
|
||||
|
||||
#endif /* BLUEGIGA_DATA_LINK_H */
|
||||
|
||||
@@ -126,7 +126,7 @@ static inline void DlCheckAndParse(void)
|
||||
#elif defined DATALINK && DATALINK == BLUEGIGA
|
||||
|
||||
#define DatalinkEvent() { \
|
||||
BlueGigaCheckAndParse(DOWNLINK_DEVICE, pprz_tp); \
|
||||
pprz_check_and_parse(&(DOWNLINK_DEVICE).device, &pprz_tp, dl_buffer, (uint8_t*)(&dl_msg_available)); \
|
||||
DlCheckAndParse(); \
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include "subsystems/gps.h"
|
||||
|
||||
#include "led.h"
|
||||
|
||||
#ifdef GPS_POWER_GPIO
|
||||
@@ -90,10 +89,11 @@ static void send_gps(struct transport_tx *trans, struct link_device *dev)
|
||||
uint8_t zero = 0;
|
||||
int16_t climb = -gps.ned_vel.z;
|
||||
int16_t course = (DegOfRad(gps.course) / ((int32_t)1e6));
|
||||
struct UtmCoor_i utm = utm_int_from_gps(&gps, 0);
|
||||
pprz_msg_send_GPS(trans, dev, AC_ID, &gps.fix,
|
||||
&gps.utm_pos.east, &gps.utm_pos.north,
|
||||
&utm.east, &utm.north,
|
||||
&course, &gps.hmsl, &gps.gspeed, &climb,
|
||||
&gps.week, &gps.tow, &gps.utm_pos.zone, &zero);
|
||||
&gps.week, &gps.tow, &utm.zone, &zero);
|
||||
// send SVINFO for available satellites that have new data
|
||||
send_svinfo_available(trans, dev);
|
||||
}
|
||||
@@ -199,3 +199,65 @@ uint32_t gps_tow_from_sys_ticks(uint32_t sys_ticks)
|
||||
void WEAK gps_inject_data(uint8_t packet_id __attribute__((unused)), uint8_t length __attribute__((unused)), uint8_t *data __attribute__((unused))){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to get utm position from GPS state
|
||||
*/
|
||||
struct UtmCoor_f utm_float_from_gps(struct GpsState *gps_s, uint8_t zone)
|
||||
{
|
||||
struct UtmCoor_f utm;
|
||||
utm.alt = 0.f;
|
||||
|
||||
if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_UTM_BIT)) {
|
||||
// A real UTM position is available, use the correct zone
|
||||
utm.zone = gps_s->utm_pos.zone;
|
||||
utm.east = gps_s->utm_pos.east / 100.0f;
|
||||
utm.north = gps_s->utm_pos.north / 100.0f;
|
||||
}
|
||||
else {
|
||||
struct LlaCoor_f lla;
|
||||
LLA_FLOAT_OF_BFP(lla, gps_s->lla_pos);
|
||||
// Check if zone should be computed
|
||||
if (zone > 0) {
|
||||
utm.zone = zone;
|
||||
} else {
|
||||
utm.zone = (gps_s->lla_pos.lon / 1e7 + 180) / 6 + 1;
|
||||
}
|
||||
/* Recompute UTM coordinates in this zone */
|
||||
utm_of_lla_f(&utm, &lla);
|
||||
}
|
||||
|
||||
return utm;
|
||||
}
|
||||
|
||||
struct UtmCoor_i utm_int_from_gps(struct GpsState *gps_s, uint8_t zone)
|
||||
{
|
||||
struct UtmCoor_i utm;
|
||||
utm.alt = 0;
|
||||
|
||||
if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_UTM_BIT)) {
|
||||
// A real UTM position is available, use the correct zone
|
||||
utm.zone = gps_s->utm_pos.zone;
|
||||
utm.east = gps_s->utm_pos.east;
|
||||
utm.north = gps_s->utm_pos.north;
|
||||
}
|
||||
else {
|
||||
struct LlaCoor_f lla;
|
||||
LLA_FLOAT_OF_BFP(lla, gps_s->lla_pos);
|
||||
// Check if zone should be computed
|
||||
if (zone > 0) {
|
||||
utm.zone = zone;
|
||||
} else {
|
||||
utm.zone = (gps_s->lla_pos.lon / 1e7 + 180) / 6 + 1;
|
||||
}
|
||||
/* Recompute UTM coordinates in this zone */
|
||||
struct UtmCoor_f utm_f;
|
||||
utm_f.zone = utm.zone;
|
||||
utm_of_lla_f(&utm_f, &lla);
|
||||
/* convert to fixed point in cm */
|
||||
utm.east = utm_f.east * 100;
|
||||
utm.north = utm_f.north * 100;
|
||||
}
|
||||
|
||||
return utm;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "std.h"
|
||||
#include "math/pprz_geodetic_int.h"
|
||||
#include "math/pprz_geodetic_float.h"
|
||||
|
||||
#include "mcu_periph/sys_time.h"
|
||||
|
||||
@@ -162,4 +163,22 @@ extern struct GpsTimeSync gps_time_sync;
|
||||
*/
|
||||
extern uint32_t gps_tow_from_sys_ticks(uint32_t sys_ticks);
|
||||
|
||||
/**
|
||||
* Convenience function to get utm position in float from GPS structure.
|
||||
* Beware that altitude is initialized to zero but not set to the correct value
|
||||
* @param[in] gps pointer to the gps structure
|
||||
* @param[in] zone set the utm zone in which the position should be computed, 0 to try to get it automatically from lla position
|
||||
* @return utm position in float
|
||||
*/
|
||||
extern struct UtmCoor_f utm_float_from_gps(struct GpsState *gps, uint8_t zone);
|
||||
|
||||
/**
|
||||
* Convenience function to get utm position in int from GPS structure.
|
||||
* Beware that altitude is initialized to zero but not set to the correct value
|
||||
* @param[in] gps pointer to the gps structure
|
||||
* @param[in] zone set the utm zone in which the position should be computed, 0 to try to get it automatically from lla position
|
||||
* @return utm position in fixed point (cm)
|
||||
*/
|
||||
extern struct UtmCoor_i utm_int_from_gps(struct GpsState *gps_s, uint8_t zone);
|
||||
|
||||
#endif /* GPS_H */
|
||||
|
||||
@@ -27,35 +27,16 @@
|
||||
* GPS structure to the values received.
|
||||
*/
|
||||
|
||||
#include "generated/flight_plan.h" // reference lla NAV_XXX0
|
||||
|
||||
#include "subsystems/gps.h"
|
||||
#include "subsystems/abi.h"
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
#if GPS_USE_DATALINK_SMALL
|
||||
#ifndef GPS_LOCAL_ECEF_ORIGIN_X
|
||||
#error Local x coordinate in ECEF of the remote GPS required
|
||||
#endif
|
||||
|
||||
#ifndef GPS_LOCAL_ECEF_ORIGIN_Y
|
||||
#error Local y coordinate in ECEF of the remote GPS required
|
||||
#endif
|
||||
|
||||
#ifndef GPS_LOCAL_ECEF_ORIGIN_Z
|
||||
#error Local z coordinate in ECEF of the remote GPS required
|
||||
#endif
|
||||
|
||||
struct EcefCoor_i tracking_ecef;
|
||||
|
||||
struct LtpDef_i tracking_ltp;
|
||||
// #include <stdio.h>
|
||||
|
||||
struct LtpDef_i ltp_def;
|
||||
struct EnuCoor_i enu_pos, enu_speed;
|
||||
|
||||
struct EcefCoor_i ecef_pos, ecef_vel;
|
||||
|
||||
struct LlaCoor_i lla_pos;
|
||||
#endif
|
||||
|
||||
bool_t gps_available; ///< Is set to TRUE when a new REMOTE_GPS packet is received and parsed
|
||||
|
||||
/** GPS initialization */
|
||||
@@ -66,70 +47,67 @@ void gps_impl_init(void)
|
||||
gps.gspeed = 700; // To enable course setting
|
||||
gps.cacc = 0; // To enable course setting
|
||||
|
||||
#if GPS_USE_DATALINK_SMALL
|
||||
tracking_ecef.x = GPS_LOCAL_ECEF_ORIGIN_X;
|
||||
tracking_ecef.y = GPS_LOCAL_ECEF_ORIGIN_Y;
|
||||
tracking_ecef.z = GPS_LOCAL_ECEF_ORIGIN_Z;
|
||||
struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */
|
||||
llh_nav0.lat = NAV_LAT0;
|
||||
llh_nav0.lon = NAV_LON0;
|
||||
/* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */
|
||||
llh_nav0.alt = NAV_ALT0 + NAV_MSL0;
|
||||
|
||||
ltp_def_from_ecef_i(&tracking_ltp, &tracking_ecef);
|
||||
#endif
|
||||
struct EcefCoor_i ecef_nav0;
|
||||
ecef_of_lla_i(&ecef_nav0, &llh_nav0);
|
||||
ltp_def_from_ecef_i(<p_def, &ecef_nav0);
|
||||
}
|
||||
|
||||
#ifdef GPS_USE_DATALINK_SMALL
|
||||
// Parse the REMOTE_GPS_SMALL datalink packet
|
||||
void parse_gps_datalink_small(uint8_t num_sv, uint32_t pos_xyz, uint32_t speed_xy)
|
||||
void parse_gps_datalink_small(uint8_t num_sv, uint32_t pos_xyz, uint32_t speed_xyz, int16_t heading)
|
||||
{
|
||||
|
||||
// Position in ENU coordinates
|
||||
enu_pos.x = (int32_t)((pos_xyz >> 22) & 0x3FF); // bits 31-22 x position in cm
|
||||
if (enu_pos.x & 0x200) {
|
||||
enu_pos.x |= 0xFFFFFC00; // fix for twos complements
|
||||
enu_pos.x = (int32_t)((pos_xyz >> 21) & 0x7FF); // bits 31-21 x position in cm
|
||||
if (enu_pos.x & 0x400) {
|
||||
enu_pos.x |= 0xFFFFF800; // sign extend for twos complements
|
||||
}
|
||||
enu_pos.y = (int32_t)((pos_xyz >> 12) & 0x3FF); // bits 21-12 y position in cm
|
||||
if (enu_pos.y & 0x200) {
|
||||
enu_pos.y |= 0xFFFFFC00; // fix for twos complements
|
||||
enu_pos.y = (int32_t)((pos_xyz >> 10) & 0x7FF); // bits 20-10 y position in cm
|
||||
if (enu_pos.y & 0x400) {
|
||||
enu_pos.y |= 0xFFFFF800; // sign extend for twos complements
|
||||
}
|
||||
enu_pos.z = (int32_t)(pos_xyz >> 2 & 0x3FF); // bits 11-2 z position in cm
|
||||
// bits 1 and 0 are free
|
||||
|
||||
// printf("ENU Pos: %u (%d, %d, %d)\n", pos_xyz, enu_pos.x, enu_pos.y, enu_pos.z);
|
||||
enu_pos.z = (int32_t)(pos_xyz & 0x3FF); // bits 9-0 z position in cm
|
||||
|
||||
// Convert the ENU coordinates to ECEF
|
||||
ecef_of_enu_point_i(&ecef_pos, &tracking_ltp, &enu_pos);
|
||||
gps.ecef_pos = ecef_pos;
|
||||
ecef_of_enu_point_i(&gps.ecef_pos, <p_def, &enu_pos);
|
||||
SetBit(gps.valid_fields, GPS_VALID_POS_ECEF_BIT);
|
||||
|
||||
lla_of_ecef_i(&lla_pos, &ecef_pos);
|
||||
gps.lla_pos = lla_pos;
|
||||
lla_of_ecef_i(&gps.lla_pos, &gps.ecef_pos);
|
||||
SetBit(gps.valid_fields, GPS_VALID_POS_LLA_BIT);
|
||||
|
||||
enu_speed.x = (int32_t)((speed_xy >> 22) & 0x3FF); // bits 31-22 speed x in cm/s
|
||||
if (enu_speed.x & 0x200) {
|
||||
enu_speed.x |= 0xFFFFFC00; // fix for twos complements
|
||||
enu_speed.x = (int32_t)((speed_xyz >> 21) & 0x7FF); // bits 31-21 speed x in cm/s
|
||||
if (enu_speed.x & 0x400) {
|
||||
enu_speed.x |= 0xFFFFF800; // sign extend for twos complements
|
||||
}
|
||||
enu_speed.y = (int32_t)((speed_xy >> 12) & 0x3FF); // bits 21-12 speed y in cm/s
|
||||
if (enu_speed.y & 0x200) {
|
||||
enu_speed.y |= 0xFFFFFC00; // fix for twos complements
|
||||
enu_speed.y = (int32_t)((speed_xyz >> 10) & 0x7FF); // bits 20-10 speed y in cm/s
|
||||
if (enu_speed.y & 0x400) {
|
||||
enu_speed.y |= 0xFFFFF800; // sign extend for twos complements
|
||||
}
|
||||
enu_speed.z = (int32_t)((speed_xyz) & 0x3FF); // bits 9-0 speed z in cm/s
|
||||
if (enu_speed.z & 0x200) {
|
||||
enu_speed.z |= 0xFFFFFC00; // sign extend for twos complements
|
||||
}
|
||||
enu_speed.z = 0;
|
||||
|
||||
// printf("ENU Speed: %u (%d, %d, %d)\n", speed_xy, enu_speed.x, enu_speed.y, enu_speed.z);
|
||||
|
||||
ecef_of_enu_vect_i(&gps.ecef_vel , &tracking_ltp , &enu_speed);
|
||||
ecef_of_enu_vect_i(&gps.ecef_vel , <p_def , &enu_speed);
|
||||
SetBit(gps.valid_fields, GPS_VALID_VEL_ECEF_BIT);
|
||||
|
||||
gps.hmsl = tracking_ltp.hmsl + enu_pos.z * 10; // TODO: try to compensate for the loss in accuracy
|
||||
gps.ned_vel.x = enu_speed.y;
|
||||
gps.ned_vel.y = enu_speed.x;
|
||||
gps.ned_vel.z = -enu_speed.z;
|
||||
SetBit(gps.valid_fields, GPS_VALID_VEL_NED_BIT);
|
||||
|
||||
gps.hmsl = ltp_def.hmsl + enu_pos.z * 10;
|
||||
SetBit(gps.valid_fields, GPS_VALID_HMSL_BIT);
|
||||
|
||||
gps.course = (int32_t)((speed_xy >> 2) & 0x3FF); // bits 11-2 heading in rad*1e2
|
||||
if (gps.course & 0x200) {
|
||||
gps.course |= 0xFFFFFC00; // fix for twos complements
|
||||
}
|
||||
// printf("Heading: %d\n", gps.course);
|
||||
gps.course *= 1e5;
|
||||
gps.course = ((int32_t)heading) * 1e3;
|
||||
SetBit(gps.valid_fields, GPS_VALID_COURSE_BIT);
|
||||
|
||||
gps.num_sv = num_sv;
|
||||
gps.tow = 0; // set time-of-weak to 0
|
||||
gps.tow = gps_tow_from_sys_ticks(sys_time.nb_tick);
|
||||
gps.fix = GPS_FIX_3D; // set 3D fix to true
|
||||
gps_available = TRUE; // set GPS available to true
|
||||
|
||||
@@ -143,7 +121,6 @@ void parse_gps_datalink_small(uint8_t num_sv, uint32_t pos_xyz, uint32_t speed_x
|
||||
}
|
||||
AbiSendMsgGPS(GPS_DATALINK_ID, now_ts, &gps);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Parse the REMOTE_GPS datalink packet */
|
||||
void parse_gps_datalink(uint8_t numsv, int32_t ecef_x, int32_t ecef_y, int32_t ecef_z, int32_t lat, int32_t lon,
|
||||
@@ -168,10 +145,20 @@ void parse_gps_datalink(uint8_t numsv, int32_t ecef_x, int32_t ecef_y, int32_t e
|
||||
gps.ecef_vel.z = ecef_zd;
|
||||
SetBit(gps.valid_fields, GPS_VALID_VEL_ECEF_BIT);
|
||||
|
||||
gps.ned_vel.x = enu_speed.y;
|
||||
gps.ned_vel.y = enu_speed.x;
|
||||
gps.ned_vel.z = -enu_speed.z;
|
||||
SetBit(gps.valid_fields, GPS_VALID_VEL_NED_BIT);
|
||||
|
||||
gps.course = course;
|
||||
SetBit(gps.valid_fields, GPS_VALID_COURSE_BIT);
|
||||
|
||||
gps.num_sv = numsv;
|
||||
gps.tow = tow;
|
||||
if (tow == 0) {
|
||||
gps.tow = gps_tow_from_sys_ticks(sys_time.nb_tick); //tow;
|
||||
} else {
|
||||
gps.tow = gps_tow_from_sys_ticks(sys_time.nb_tick); //tow;
|
||||
}
|
||||
gps.fix = GPS_FIX_3D;
|
||||
gps_available = TRUE;
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
#define GPS_NB_CHANNELS 0
|
||||
|
||||
extern bool_t gps_available;
|
||||
#ifdef GPS_USE_DATALINK_SMALL
|
||||
void parse_gps_datalink_small(uint8_t num_sv, uint32_t pos_xyz, uint32_t speed_xy);
|
||||
#endif
|
||||
|
||||
extern void parse_gps_datalink_small(uint8_t num_sv, uint32_t pos_xyz, uint32_t speed_xyz, int16_t heading);
|
||||
|
||||
extern void parse_gps_datalink(uint8_t numsv, int32_t ecef_x, int32_t ecef_y, int32_t ecef_z,
|
||||
int32_t lat, int32_t lon, int32_t alt, int32_t hmsl,
|
||||
int32_t ecef_xd, int32_t ecef_yd, int32_t ecef_zd,
|
||||
|
||||
@@ -72,20 +72,7 @@ void ins_init(void)
|
||||
void WEAK ins_reset_local_origin(void)
|
||||
{
|
||||
#if USE_GPS
|
||||
struct UtmCoor_f utm;
|
||||
|
||||
if (bit_is_set(gps.valid_fields, GPS_VALID_POS_UTM_BIT)) {
|
||||
utm.zone = gps.utm_pos.zone;
|
||||
utm.east = gps.utm_pos.east / 100.0f;
|
||||
utm.north = gps.utm_pos.north / 100.0f;
|
||||
}
|
||||
else {
|
||||
/* Recompute UTM coordinates in this zone */
|
||||
struct LlaCoor_f lla;
|
||||
LLA_FLOAT_OF_BFP(lla, gps.lla_pos);
|
||||
utm.zone = (gps.lla_pos.lon / 1e7 + 180) / 6 + 1;
|
||||
utm_of_lla_f(&utm, &lla);
|
||||
}
|
||||
struct UtmCoor_f utm = utm_float_from_gps(&gps, 0);
|
||||
|
||||
// ground_alt
|
||||
utm.alt = gps.hmsl / 1000.0f;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user