diff --git a/conf/airframes/ENAC/fixed-wing/apogee.xml b/conf/airframes/ENAC/fixed-wing/apogee.xml
index afe5f8a96f..d98be030f0 100644
--- a/conf/airframes/ENAC/fixed-wing/apogee.xml
+++ b/conf/airframes/ENAC/fixed-wing/apogee.xml
@@ -8,6 +8,9 @@
+
+
+
@@ -21,6 +24,7 @@
+
@@ -38,6 +42,7 @@
+
diff --git a/conf/airframes/examples/MentorEnergy.xml b/conf/airframes/examples/MentorEnergy.xml
index 39c98a1283..9416ac28b8 100644
--- a/conf/airframes/examples/MentorEnergy.xml
+++ b/conf/airframes/examples/MentorEnergy.xml
@@ -9,7 +9,6 @@
-
@@ -27,7 +26,6 @@
-
-
+
diff --git a/conf/airframes/examples/krooz_sd/fixedwing/krooz_sd_fw.xml b/conf/airframes/examples/krooz_sd/fixedwing/krooz_sd_fw.xml
new file mode 100644
index 0000000000..7c0ab8835c
--- /dev/null
+++ b/conf/airframes/examples/krooz_sd/fixedwing/krooz_sd_fw.xml
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml b/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml
old mode 100755
new mode 100644
index 00c0fd5239..36e979ea40
--- a/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml
+++ b/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml
@@ -17,7 +17,7 @@
-
+
@@ -91,23 +91,23 @@
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -123,7 +123,7 @@
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml b/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml
old mode 100755
new mode 100644
index 916d281c06..40786c6218
--- a/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml
+++ b/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml
@@ -17,7 +17,7 @@
-
+
@@ -94,23 +94,23 @@
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -126,7 +126,7 @@
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml b/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml
old mode 100755
new mode 100644
index c018d28048..0b31cd058e
--- a/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml
+++ b/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml
@@ -15,7 +15,7 @@
-
+
@@ -84,16 +84,16 @@
-
-
-
+
+
+
-
-
-
+
+
+
@@ -116,7 +116,7 @@
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml b/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml
old mode 100755
new mode 100644
index 88b83d3cf3..9f3d371545
--- a/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml
+++ b/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml
@@ -19,7 +19,7 @@
-
+
@@ -79,27 +79,27 @@
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/conf/airframes/examples/quadshot_asp21_spektrum.xml b/conf/airframes/examples/quadshot_asp21_spektrum.xml
index 8f583e899b..1c3262b131 100644
--- a/conf/airframes/examples/quadshot_asp21_spektrum.xml
+++ b/conf/airframes/examples/quadshot_asp21_spektrum.xml
@@ -246,7 +246,7 @@ More information on the Quadshot can be found at transition-robotics.com -->
-
+
diff --git a/conf/airframes/flixr_discovery.xml b/conf/airframes/flixr_discovery.xml
index c19b65dddd..84cc1f6305 100644
--- a/conf/airframes/flixr_discovery.xml
+++ b/conf/airframes/flixr_discovery.xml
@@ -67,7 +67,7 @@
diff --git a/conf/airframes/obsolete/mm/fixed-wing/slowfast2.xml b/conf/airframes/obsolete/mm/fixed-wing/slowfast2.xml
index ce6d0b7f49..8a0c6e8042 100644
--- a/conf/airframes/obsolete/mm/fixed-wing/slowfast2.xml
+++ b/conf/airframes/obsolete/mm/fixed-wing/slowfast2.xml
@@ -36,7 +36,7 @@
-
+
diff --git a/conf/firmwares/rotorcraft.makefile b/conf/firmwares/rotorcraft.makefile
index e3ae4a8c97..bd5519ef4c 100644
--- a/conf/firmwares/rotorcraft.makefile
+++ b/conf/firmwares/rotorcraft.makefile
@@ -201,6 +201,10 @@ ap.CFLAGS += -DUSE_SPI1
ap.srcs += peripherals/mcp355x.c
ap.srcs += $(SRC_BOARD)/baro_board.c
+# krooz baro
+else ifeq ($(BOARD), krooz)
+ap.srcs += $(SRC_BOARD)/baro_board.c
+
# apogee baro
else ifeq ($(BOARD), apogee)
ap.CFLAGS += -DUSE_I2C1
diff --git a/conf/firmwares/subsystems/shared/imu_aspirin_v2.1_old.makefile b/conf/firmwares/subsystems/shared/imu_aspirin_v2.1_old.makefile
deleted file mode 100644
index 446b84af59..0000000000
--- a/conf/firmwares/subsystems/shared/imu_aspirin_v2.1_old.makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-# Hey Emacs, this is a -*- makefile -*-
-#
-# Aspirin IMU v2.1
-#
-#
-# required xml:
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-#
-
-
-# for fixedwing firmware and ap only
-ifeq ($(TARGET), ap)
- IMU_ASPIRIN_CFLAGS = -DUSE_IMU
-endif
-
-IMU_ASPIRIN_CFLAGS += -DIMU_TYPE_H=\"imu/imu_aspirin2.h\"
-IMU_ASPIRIN_SRCS = $(SRC_SUBSYSTEMS)/imu.c \
- $(SRC_SUBSYSTEMS)/imu/imu_aspirin2.c
-
-include $(CFG_SHARED)/spi_master.makefile
-
-ifeq ($(ARCH), lpc21)
-IMU_ASPIRIN_CFLAGS += -DUSE_SPI1
-IMU_ASPIRIN_CFLAGS += -DUSE_SPI_SLAVE0
-else ifeq ($(ARCH), stm32)
-IMU_ASPIRIN_CFLAGS += -DUSE_SPI2
-# Slave select configuration
-# SLAVE2 is on PB12 (NSS) (MPU600 CS)
-IMU_ASPIRIN_CFLAGS += -DUSE_SPI_SLAVE2
-endif
-
-IMU_ASPIRIN_CFLAGS += -DIMU_ASPIRIN_VERSION_2_1
-
-# Keep CFLAGS/Srcs for imu in separate expression so we can assign it to other targets
-# see: conf/autopilot/subsystems/lisa_passthrough/imu_b2_v1.1.makefile for example
-
-ap.CFLAGS += $(IMU_ASPIRIN_CFLAGS)
-ap.srcs += $(IMU_ASPIRIN_SRCS)
-
-
-#
-# NPS simulator
-#
-include $(CFG_SHARED)/imu_nps.makefile
diff --git a/conf/firmwares/subsystems/shared/imu_krooz_sd.makefile b/conf/firmwares/subsystems/shared/imu_krooz_sd.makefile
new file mode 100644
index 0000000000..c2a7e83fe0
--- /dev/null
+++ b/conf/firmwares/subsystems/shared/imu_krooz_sd.makefile
@@ -0,0 +1,29 @@
+# Hey Emacs, this is a -*- makefile -*-
+#
+# KroozSD IMU
+#
+
+IMU_KROOZ_CFLAGS = -DUSE_IMU
+IMU_KROOZ_CFLAGS += -DIMU_TYPE_H=\"boards/krooz/imu_krooz.h\"
+
+IMU_KROOZ_SRCS = $(SRC_SUBSYSTEMS)/imu.c \
+ $(SRC_BOARD)/imu_krooz.c \
+ $(SRC_ARCH)/subsystems/imu/imu_krooz_sd_arch.c
+
+IMU_KROOZ_I2C_DEV=i2c2
+IMU_KROOZ_CFLAGS += -DUSE_I2C -DUSE_I2C2 -DI2C2_CLOCK_SPEED=400000
+
+IMU_KROOZ_CFLAGS += -DIMU_KROOZ_I2C_DEV=$(IMU_KROOZ_I2C_DEV)
+IMU_KROOZ_CFLAGS += -DMS5611_I2C_DEV=$(IMU_KROOZ_I2C_DEV) -DMS5611_SLAVE_ADDR=0xEC
+IMU_KROOZ_SRCS += peripherals/mpu60x0.c
+IMU_KROOZ_SRCS += peripherals/mpu60x0_i2c.c
+IMU_KROOZ_SRCS += peripherals/hmc58xx.c
+IMU_KROOZ_SRCS += modules/sensors/baro_ms5611_i2c.c
+
+AHRS_PROPAGATE_FREQUENCY ?= 512
+AHRS_CORRECT_FREQUENCY ?= 512
+ap.CFLAGS += -DAHRS_PROPAGATE_FREQUENCY=$(AHRS_PROPAGATE_FREQUENCY)
+ap.CFLAGS += -DAHRS_CORRECT_FREQUENCY=$(AHRS_CORRECT_FREQUENCY)
+
+ap.CFLAGS += $(IMU_KROOZ_CFLAGS)
+ap.srcs += $(IMU_KROOZ_SRCS)
diff --git a/conf/modules/airspeed_ets.xml b/conf/modules/airspeed_ets.xml
index de10d509a9..07cf003315 100644
--- a/conf/modules/airspeed_ets.xml
+++ b/conf/modules/airspeed_ets.xml
@@ -17,11 +17,12 @@
- Yellow wire: SDA
- Brown wire: SCL
-
-
-
+
+
+
+
-
+
diff --git a/conf/modules/baro_amsys.xml b/conf/modules/baro_amsys.xml
index acd6f98b46..2b94bb226c 100644
--- a/conf/modules/baro_amsys.xml
+++ b/conf/modules/baro_amsys.xml
@@ -7,6 +7,10 @@
Module to read a Amsys AMS 5812-0150-A barometric sensor via I2C.
+
+
+
+
diff --git a/conf/modules/baro_ets.xml b/conf/modules/baro_ets.xml
index 48b79418a0..0b59c2a45b 100644
--- a/conf/modules/baro_ets.xml
+++ b/conf/modules/baro_ets.xml
@@ -2,10 +2,26 @@
- Baro ETS (I2C)
-
-
-
+
+ Baro ETS (I2C).
+ Driver for the EagleTree Systems Baro Sensor.
+ Has only been tested with V3 of the sensor hardware.
+
+ Notes:
+ Connect directly to TWOG/Tiny I2C port. Multiple sensors can be chained together.
+ Sensor should be in the proprietary mode (default) and not in 3rd party mode.
+
+ Sensor module wire assignments:
+ - Red wire: 5V
+ - White wire: Ground
+ - Yellow wire: SDA
+ - Brown wire: SCL
+
+
+
+
+
+
diff --git a/sw/airborne/arch/stm32/mcu_periph/spi_arch.c b/sw/airborne/arch/stm32/mcu_periph/spi_arch.c
index 4384d15686..bb5d82876c 100644
--- a/sw/airborne/arch/stm32/mcu_periph/spi_arch.c
+++ b/sw/airborne/arch/stm32/mcu_periph/spi_arch.c
@@ -84,15 +84,17 @@ struct spi_periph_dma {
uint32_t spi; ///< SPI peripheral identifier
uint32_t spidr; ///< SPI DataRegister address for DMA
uint32_t dma; ///< DMA controller base address (DMA1 or DMA2)
- uint8_t rx_chan; ///< receive DMA channel number
- uint8_t tx_chan; ///< transmit DMA channel number
+ uint8_t rx_chan; ///< receive DMA channel (or stream on F4) number
+ uint8_t tx_chan; ///< transmit DMA channel (or stream on F4) number
+ uint32_t rx_chan_sel; ///< F4 only: actual receive DMA channel number
+ uint32_t tx_chan_sel; ///< F4 only: actual transmit DMA channel number
uint8_t rx_nvic_irq; ///< receive interrupt
uint8_t tx_nvic_irq; ///< transmit interrupt
uint16_t tx_dummy_buf; ///< dummy tx buffer for receive only cases
- bool_t tx_extra_dummy_dma; ///< extra tx dummy dma flag for tx_len < rx_len
+ bool_t tx_extra_dummy_dma; ///< extra tx dummy dma flag for tx_len < rx_len
uint16_t rx_dummy_buf; ///< dummy rx buffer for receive only cases
- bool_t rx_extra_dummy_dma; ///< extra rx dummy dma flag for tx_len > rx_len
- struct locm3_spi_comm comm; ///< current communication paramters
+ bool_t rx_extra_dummy_dma; ///< extra rx dummy dma flag for tx_len > rx_len
+ struct locm3_spi_comm comm; ///< current communication paramters
uint8_t comm_sig; ///< comm config signature used to check for changes
};
@@ -439,12 +441,17 @@ static void set_comm_from_transaction(struct locm3_spi_comm* c, struct spi_trans
static void spi_configure_dma(uint32_t dma, uint8_t chan, uint32_t periph_addr, uint32_t buf_addr,
uint16_t len, enum SPIDataSizeSelect dss, bool_t increment)
{
+#ifdef STM32F1
dma_channel_reset(dma, chan);
+#elif defined STM32F4
+ dma_stream_reset(dma, chan);
+#endif
dma_set_peripheral_address(dma, chan, periph_addr);
dma_set_memory_address(dma, chan, buf_addr);
dma_set_number_of_data(dma, chan, len);
/* Set the dma transfer size based on SPI transaction DSS */
+#ifdef STM32F1
if (dss == SPIDss8bit) {
dma_set_peripheral_size(dma, chan, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(dma, chan, DMA_CCR_MSIZE_8BIT);
@@ -452,6 +459,15 @@ static void spi_configure_dma(uint32_t dma, uint8_t chan, uint32_t periph_addr,
dma_set_peripheral_size(dma, chan, DMA_CCR_PSIZE_16BIT);
dma_set_memory_size(dma, chan, DMA_CCR_MSIZE_16BIT);
}
+#elif defined STM32F4
+ if (dss == SPIDss8bit) {
+ dma_set_peripheral_size(dma, chan, DMA_SxCR_PSIZE_8BIT);
+ dma_set_memory_size(dma, chan, DMA_SxCR_MSIZE_8BIT);
+ } else {
+ dma_set_peripheral_size(dma, chan, DMA_SxCR_PSIZE_16BIT);
+ dma_set_memory_size(dma, chan, DMA_SxCR_MSIZE_16BIT);
+ }
+#endif
if (increment)
dma_enable_memory_increment_mode(dma, chan);
@@ -566,8 +582,14 @@ static void spi_start_dma_transaction(struct spi_periph* periph, struct spi_tran
dma->rx_extra_dummy_dma = TRUE;
}
}
+#ifdef STM32F1
dma_set_read_from_peripheral(dma->dma, dma->rx_chan);
dma_set_priority(dma->dma, dma->rx_chan, DMA_CCR_PL_VERY_HIGH);
+#elif defined STM32F4
+ dma_channel_select(dma->dma, dma->rx_chan, dma->rx_chan_sel);
+ dma_set_transfer_mode(dma->dma, dma->rx_chan, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
+ dma_set_priority(dma->dma, dma->rx_chan, DMA_SxCR_PL_VERY_HIGH);
+#endif
/*
@@ -591,17 +613,27 @@ static void spi_start_dma_transaction(struct spi_periph* periph, struct spi_tran
dma->tx_extra_dummy_dma = TRUE;
}
}
+#ifdef STM32F1
dma_set_read_from_memory(dma->dma, dma->tx_chan);
dma_set_priority(dma->dma, dma->tx_chan, DMA_CCR_PL_MEDIUM);
-
+#elif defined STM32F4
+ dma_channel_select(dma->dma, dma->tx_chan, dma->tx_chan_sel);
+ dma_set_transfer_mode(dma->dma, dma->tx_chan, DMA_SxCR_DIR_MEM_TO_PERIPHERAL);
+ dma_set_priority(dma->dma, dma->tx_chan, DMA_SxCR_PL_MEDIUM);
+#endif
/* Enable DMA transfer complete interrupts. */
dma_enable_transfer_complete_interrupt(dma->dma, dma->rx_chan);
dma_enable_transfer_complete_interrupt(dma->dma, dma->tx_chan);
/* Enable DMA channels */
+#ifdef STM32F1
dma_enable_channel(dma->dma, dma->rx_chan);
dma_enable_channel(dma->dma, dma->tx_chan);
+#elif defined STM32F4
+ dma_enable_stream(dma->dma, dma->rx_chan);
+ dma_enable_stream(dma->dma, dma->tx_chan);
+#endif
/* Enable SPI transfers via DMA */
spi_enable_rx_dma((uint32_t)periph->reg_addr);
@@ -620,11 +652,22 @@ void spi1_arch_init(void) {
// set dma options
spi1_dma.spidr = (uint32_t)&SPI1_DR;
+#ifdef STM32F1
spi1_dma.dma = DMA1;
spi1_dma.rx_chan = DMA_CHANNEL2;
spi1_dma.tx_chan = DMA_CHANNEL3;
spi1_dma.rx_nvic_irq = NVIC_DMA1_CHANNEL2_IRQ;
spi1_dma.tx_nvic_irq = NVIC_DMA1_CHANNEL3_IRQ;
+#elif defined STM32F4
+ spi1_dma.dma = DMA2;
+ // TODO make a macro to configure this from board/airframe file ?
+ spi1_dma.rx_chan = DMA_STREAM0;
+ spi1_dma.tx_chan = DMA_STREAM3;
+ spi1_dma.rx_chan_sel = DMA_SxCR_CHSEL_3;
+ spi1_dma.tx_chan_sel = DMA_SxCR_CHSEL_3;
+ spi1_dma.rx_nvic_irq = NVIC_DMA2_STREAM0_IRQ;
+ spi1_dma.tx_nvic_irq = NVIC_DMA2_STREAM3_IRQ;
+#endif
spi1_dma.tx_dummy_buf = 0;
spi1_dma.tx_extra_dummy_dma = FALSE;
spi1_dma.rx_dummy_buf = 0;
@@ -646,12 +689,22 @@ void spi1_arch_init(void) {
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_SPI1EN);
// Configure GPIOs: SCK, MISO and MOSI
+#ifdef STM32F1
+ // TODO configure lisa board files to use gpio_setup_pin_af function
gpio_set_mode(GPIO_BANK_SPI1_SCK, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO_SPI1_SCK | GPIO_SPI1_MOSI);
gpio_set_mode(GPIO_BANK_SPI1_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO_SPI1_MISO);
+#elif defined STM32F4
+ gpio_setup_pin_af(SPI1_GPIO_PORT_MISO, SPI1_GPIO_MISO, SPI1_GPIO_AF, FALSE);
+ gpio_setup_pin_af(SPI1_GPIO_PORT_MOSI, SPI1_GPIO_MOSI, SPI1_GPIO_AF, TRUE);
+ gpio_setup_pin_af(SPI1_GPIO_PORT_SCK, SPI1_GPIO_SCK, SPI1_GPIO_AF, TRUE);
+
+ gpio_set_output_options(SPI1_GPIO_PORT_MOSI, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI1_GPIO_MOSI);
+ gpio_set_output_options(SPI1_GPIO_PORT_SCK, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI1_GPIO_SCK);
+#endif
// reset SPI
spi_reset(SPI1);
@@ -677,7 +730,11 @@ void spi1_arch_init(void) {
spi_set_nss_high(SPI1);
// Enable SPI_1 DMA clock
+#ifdef STM32F1
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_DMA1EN);
+#elif defined STM32F4
+ rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_DMA2EN);
+#endif
// Enable SPI1 periph.
spi_enable(SPI1);
@@ -692,10 +749,19 @@ void spi2_arch_init(void) {
// set dma options
spi2_dma.spidr = (uint32_t)&SPI2_DR;
spi2_dma.dma = DMA1;
+#ifdef STM32F1
spi2_dma.rx_chan = DMA_CHANNEL4;
spi2_dma.tx_chan = DMA_CHANNEL5;
spi2_dma.rx_nvic_irq = NVIC_DMA1_CHANNEL4_IRQ;
spi2_dma.tx_nvic_irq = NVIC_DMA1_CHANNEL5_IRQ;
+#elif defined STM32F4
+ spi2_dma.rx_chan = DMA_STREAM3;
+ spi2_dma.tx_chan = DMA_STREAM4;
+ spi2_dma.rx_chan_sel = DMA_SxCR_CHSEL_0;
+ spi2_dma.tx_chan_sel = DMA_SxCR_CHSEL_0;
+ spi2_dma.rx_nvic_irq = NVIC_DMA1_STREAM3_IRQ;
+ spi2_dma.tx_nvic_irq = NVIC_DMA1_STREAM4_IRQ;
+#endif
spi2_dma.tx_dummy_buf = 0;
spi2_dma.tx_extra_dummy_dma = FALSE;
spi2_dma.rx_dummy_buf = 0;
@@ -717,12 +783,22 @@ void spi2_arch_init(void) {
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_SPI2EN);
// Configure GPIOs: SCK, MISO and MOSI
+#ifdef STM32F1
+ // TODO configure lisa board files to use gpio_setup_pin_af function
gpio_set_mode(GPIO_BANK_SPI2_SCK, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO_SPI2_SCK | GPIO_SPI2_MOSI);
gpio_set_mode(GPIO_BANK_SPI2_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO_SPI2_MISO);
+#elif defined STM32F4
+ gpio_setup_pin_af(SPI2_GPIO_PORT_MISO, SPI2_GPIO_MISO, SPI2_GPIO_AF, FALSE);
+ gpio_setup_pin_af(SPI2_GPIO_PORT_MOSI, SPI2_GPIO_MOSI, SPI2_GPIO_AF, TRUE);
+ gpio_setup_pin_af(SPI2_GPIO_PORT_SCK, SPI2_GPIO_SCK, SPI2_GPIO_AF, TRUE);
+
+ gpio_set_output_options(SPI2_GPIO_PORT_MOSI, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI2_GPIO_MOSI);
+ gpio_set_output_options(SPI2_GPIO_PORT_SCK, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI2_GPIO_SCK);
+#endif
// reset SPI
spi_reset(SPI2);
@@ -747,7 +823,11 @@ void spi2_arch_init(void) {
spi_set_nss_high(SPI2);
// Enable SPI_2 DMA clock
+#ifdef STM32F1
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_DMA1EN);
+#elif defined STM32F4
+ rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_DMA1EN);
+#endif
// Enable SPI2 periph.
spi_enable(SPI2);
@@ -761,11 +841,21 @@ void spi3_arch_init(void) {
// set the default configuration
spi3_dma.spidr = (uint32_t)&SPI3_DR;
+#ifdef STM32F1
spi3_dma.dma = DMA2;
spi3_dma.rx_chan = DMA_CHANNEL1;
spi3_dma.tx_chan = DMA_CHANNEL2;
spi3_dma.rx_nvic_irq = NVIC_DMA2_CHANNEL1_IRQ;
spi3_dma.tx_nvic_irq = NVIC_DMA2_CHANNEL2_IRQ;
+#elif defined STM32F4
+ spi3_dma.dma = DMA1;
+ spi3_dma.rx_chan = DMA_STREAM0;
+ spi3_dma.tx_chan = DMA_STREAM5;
+ spi3_dma.rx_chan_sel = DMA_SxCR_CHSEL_0;
+ spi3_dma.tx_chan_sel = DMA_SxCR_CHSEL_0;
+ spi3_dma.rx_nvic_irq = NVIC_DMA1_STREAM0_IRQ;
+ spi3_dma.tx_nvic_irq = NVIC_DMA1_STREAM5_IRQ;
+#endif
spi3_dma.tx_dummy_buf = 0;
spi3_dma.tx_extra_dummy_dma = FALSE;
spi3_dma.rx_dummy_buf = 0;
@@ -787,12 +877,22 @@ void spi3_arch_init(void) {
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_SPI3EN);
// Configure GPIOs: SCK, MISO and MOSI
+#ifdef STM32F1
+ // TODO configure lisa board files to use gpio_setup_pin_af function
gpio_set_mode(GPIO_BANK_SPI3_SCK, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO_SPI3_SCK | GPIO_SPI3_MOSI);
gpio_set_mode(GPIO_BANK_SPI3_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO_SPI3_MISO);
+#elif defined STM32F4
+ gpio_setup_pin_af(SPI3_GPIO_PORT_MISO, SPI3_GPIO_MISO, SPI3_GPIO_AF, FALSE);
+ gpio_setup_pin_af(SPI3_GPIO_PORT_MOSI, SPI3_GPIO_MOSI, SPI3_GPIO_AF, TRUE);
+ gpio_setup_pin_af(SPI3_GPIO_PORT_SCK, SPI3_GPIO_SCK, SPI3_GPIO_AF, TRUE);
+
+ gpio_set_output_options(SPI3_GPIO_PORT_MOSI, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI3_GPIO_MOSI);
+ gpio_set_output_options(SPI3_GPIO_PORT_SCK, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI3_GPIO_SCK);
+#endif
/// @todo disable JTAG so the pins can be used?
@@ -819,7 +919,11 @@ void spi3_arch_init(void) {
spi_set_nss_high(SPI3);
// Enable SPI_3 DMA clock
+#ifdef STM32F1
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_DMA2EN);
+#elif defined STM32F4
+ rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_DMA1EN);
+#endif
// Enable SPI3 periph.
spi_enable(SPI3);
@@ -838,22 +942,40 @@ void spi3_arch_init(void) {
*****************************************************************************/
#ifdef USE_SPI1
/// receive transferred over DMA
+#ifdef STM32F1
void dma1_channel2_isr(void)
{
if ((DMA1_ISR & DMA_ISR_TCIF2) != 0) {
// clear int pending bit
DMA1_IFCR |= DMA_IFCR_CTCIF2;
}
+#elif defined STM32F4
+void dma2_stream0_isr(void)
+{
+ if ((DMA2_LISR & DMA_LISR_TCIF0) != 0) {
+ // clear int pending bit
+ DMA2_LIFCR |= DMA_LIFCR_CTCIF0;
+ }
+#endif
process_rx_dma_interrupt(&spi1);
}
/// transmit transferred over DMA
+#ifdef STM32F1
void dma1_channel3_isr(void)
{
if ((DMA1_ISR & DMA_ISR_TCIF3) != 0) {
// clear int pending bit
DMA1_IFCR |= DMA_IFCR_CTCIF3;
}
+#elif defined STM32F4
+void dma2_stream3_isr(void)
+{
+ if ((DMA2_LISR & DMA_LISR_TCIF3) != 0) {
+ // clear int pending bit
+ DMA2_LIFCR |= DMA_LIFCR_CTCIF3;
+ }
+#endif
process_tx_dma_interrupt(&spi1);
}
@@ -861,22 +983,40 @@ void dma1_channel3_isr(void)
#ifdef USE_SPI2
/// receive transferred over DMA
+#ifdef STM32F1
void dma1_channel4_isr(void)
{
if ((DMA1_ISR & DMA_ISR_TCIF4) != 0) {
// clear int pending bit
DMA1_IFCR |= DMA_IFCR_CTCIF4;
}
+#elif defined STM32F4
+void dma1_stream3_isr(void)
+{
+ if ((DMA1_LISR & DMA_LISR_TCIF3) != 0) {
+ // clear int pending bit
+ DMA1_LIFCR |= DMA_LIFCR_CTCIF3;
+ }
+#endif
process_rx_dma_interrupt(&spi2);
}
/// transmit transferred over DMA
+#ifdef STM32F1
void dma1_channel5_isr(void)
{
if ((DMA1_ISR & DMA_ISR_TCIF5) != 0) {
// clear int pending bit
DMA1_IFCR |= DMA_IFCR_CTCIF5;
}
+#elif defined STM32F4
+void dma1_stream4_isr(void)
+{
+ if ((DMA1_HISR & DMA_HISR_TCIF4) != 0) {
+ // clear int pending bit
+ DMA1_HIFCR |= DMA_HIFCR_CTCIF4;
+ }
+#endif
process_tx_dma_interrupt(&spi2);
}
@@ -884,22 +1024,40 @@ void dma1_channel5_isr(void)
#if USE_SPI3
/// receive transferred over DMA
+#ifdef STM32F1
void dma2_channel1_isr(void)
{
if ((DMA2_ISR & DMA_ISR_TCIF1) != 0) {
// clear int pending bit
DMA2_IFCR |= DMA_IFCR_CTCIF1;
}
+#elif defined STM32F4
+void dma1_stream0_isr(void)
+{
+ if ((DMA1_LISR & DMA_LISR_TCIF0) != 0) {
+ // clear int pending bit
+ DMA1_LIFCR |= DMA_LIFCR_CTCIF0;
+ }
+#endif
process_rx_dma_interrupt(&spi3);
}
/// transmit transferred over DMA
+#ifdef STM32F1
void dma2_channel2_isr(void)
{
if ((DMA2_ISR & DMA_ISR_TCIF2) != 0) {
// clear int pending bit
DMA2_IFCR |= DMA_IFCR_CTCIF2;
}
+#elif defined STM32F4
+void dma1_stream5_isr(void)
+{
+ if ((DMA1_HISR & DMA_HISR_TCIF5) != 0) {
+ // clear int pending bit
+ DMA1_HIFCR |= DMA_HIFCR_CTCIF5;
+ }
+#endif
process_tx_dma_interrupt(&spi3);
}
@@ -917,7 +1075,11 @@ void process_rx_dma_interrupt(struct spi_periph *periph) {
spi_disable_rx_dma((uint32_t)periph->reg_addr);
/* Disable DMA rx channel */
+#ifdef STM32F1
dma_disable_channel(dma->dma, dma->rx_chan);
+#elif defined STM32F4
+ dma_disable_stream(dma->dma, dma->rx_chan);
+#endif
if (dma->rx_extra_dummy_dma) {
@@ -935,13 +1097,23 @@ void process_rx_dma_interrupt(struct spi_periph *periph) {
spi_configure_dma(dma->dma, dma->rx_chan, (uint32_t)dma->spidr,
(uint32_t)&(dma->rx_dummy_buf), len_remaining, trans->dss, FALSE);
+#ifdef STM32F1
dma_set_read_from_peripheral(dma->dma, dma->rx_chan);
dma_set_priority(dma->dma, dma->rx_chan, DMA_CCR_PL_HIGH);
+#elif defined STM32F4
+ dma_channel_select(dma->dma, dma->rx_chan, dma->rx_chan_sel);
+ dma_set_transfer_mode(dma->dma, dma->rx_chan, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
+ dma_set_priority(dma->dma, dma->rx_chan, DMA_SxCR_PL_HIGH);
+#endif
/* Enable DMA transfer complete interrupts. */
dma_enable_transfer_complete_interrupt(dma->dma, dma->rx_chan);
/* Enable DMA channels */
+#ifdef STM32F1
dma_enable_channel(dma->dma, dma->rx_chan);
+#elif defined STM32F4
+ dma_enable_stream(dma->dma, dma->rx_chan);
+#endif
/* Enable SPI transfers via DMA */
spi_enable_rx_dma((uint32_t)periph->reg_addr);
}
@@ -979,7 +1151,11 @@ void process_tx_dma_interrupt(struct spi_periph *periph) {
spi_disable_tx_dma((uint32_t)periph->reg_addr);
/* Disable DMA tx channel */
+#ifdef STM32F1
dma_disable_channel(dma->dma, dma->tx_chan);
+#elif defined STM32F4
+ dma_disable_stream(dma->dma, dma->tx_chan);
+#endif
if (dma->tx_extra_dummy_dma) {
/*
@@ -996,13 +1172,23 @@ void process_tx_dma_interrupt(struct spi_periph *periph) {
spi_configure_dma(dma->dma, dma->tx_chan, (uint32_t)dma->spidr,
(uint32_t)&(dma->tx_dummy_buf), len_remaining, trans->dss, FALSE);
+#ifdef STM32F1
dma_set_read_from_memory(dma->dma, dma->tx_chan);
dma_set_priority(dma->dma, dma->tx_chan, DMA_CCR_PL_MEDIUM);
+#elif defined STM32F4
+ dma_channel_select(dma->dma, dma->tx_chan, dma->tx_chan_sel);
+ dma_set_transfer_mode(dma->dma, dma->tx_chan, DMA_SxCR_DIR_MEM_TO_PERIPHERAL);
+ dma_set_priority(dma->dma, dma->tx_chan, DMA_SxCR_PL_MEDIUM);
+#endif
/* Enable DMA transfer complete interrupts. */
dma_enable_transfer_complete_interrupt(dma->dma, dma->tx_chan);
/* Enable DMA channels */
+#ifdef STM32F1
dma_enable_channel(dma->dma, dma->tx_chan);
+#elif defined STM32F4
+ dma_enable_stream(dma->dma, dma->tx_chan);
+#endif
/* Enable SPI transfers via DMA */
spi_enable_tx_dma((uint32_t)periph->reg_addr);
diff --git a/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c b/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c
index 4a56067c5a..6a4ba6bf7e 100644
--- a/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c
+++ b/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c
@@ -208,6 +208,9 @@ void actuators_pwm_arch_init(void) {
#ifdef PWM_SERVO_8
set_servo_gpio(PWM_SERVO_8_GPIO, PWM_SERVO_8_PIN, PWM_SERVO_8_AF, PWM_SERVO_8_RCC_IOP);
#endif
+#ifdef PWM_SERVO_9
+ set_servo_gpio(PWM_SERVO_9_GPIO, PWM_SERVO_9_PIN, PWM_SERVO_9_AF, PWM_SERVO_9_RCC_IOP);
+#endif
#if PWM_USE_TIM1
@@ -262,5 +265,8 @@ void actuators_pwm_commit(void) {
#ifdef PWM_SERVO_8
timer_set_oc_value(PWM_SERVO_8_TIMER, PWM_SERVO_8_OC, actuators_pwm_values[PWM_SERVO_8]);
#endif
+#ifdef PWM_SERVO_9
+ timer_set_oc_value(PWM_SERVO_9_TIMER, PWM_SERVO_9_OC, actuators_pwm_values[PWM_SERVO_9]);
+#endif
}
diff --git a/sw/airborne/arch/stm32/subsystems/imu/imu_krooz_sd_arch.c b/sw/airborne/arch/stm32/subsystems/imu/imu_krooz_sd_arch.c
new file mode 100644
index 0000000000..64ef448548
--- /dev/null
+++ b/sw/airborne/arch/stm32/subsystems/imu/imu_krooz_sd_arch.c
@@ -0,0 +1,37 @@
+#include "subsystems/imu.h"
+
+#include
+#include
+#include
+#include
+
+#include "subsystems/imu/imu_krooz_sd_arch.h"
+
+void imu_krooz_sd_arch_init(void) {
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_SYSCFGEN);
+ rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPBEN);
+ rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPCEN);
+ gpio_mode_setup(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO5);
+ gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO6);
+
+ nvic_enable_irq(NVIC_EXTI9_5_IRQ);
+ exti_select_source(EXTI5, GPIOB);
+ exti_select_source(EXTI6, GPIOC);
+ exti_set_trigger(EXTI5, EXTI_TRIGGER_RISING);
+ exti_set_trigger(EXTI6, EXTI_TRIGGER_FALLING);
+ exti_enable_request(EXTI5);
+ exti_enable_request(EXTI6);
+ nvic_set_priority(NVIC_EXTI9_5_IRQ, 0x0F);
+}
+
+void exti9_5_isr(void) {
+ /* clear EXTI */
+ if(EXTI_PR & EXTI6) {
+ exti_reset_request(EXTI6);
+ hmc58xx_read(&imu_krooz.hmc);
+ }
+ if(EXTI_PR & EXTI5) {
+ exti_reset_request(EXTI5);
+ mpu60x0_i2c_read(&imu_krooz.mpu);
+ }
+}
diff --git a/sw/airborne/arch/stm32/subsystems/imu/imu_krooz_sd_arch.h b/sw/airborne/arch/stm32/subsystems/imu/imu_krooz_sd_arch.h
new file mode 100644
index 0000000000..3917845d68
--- /dev/null
+++ b/sw/airborne/arch/stm32/subsystems/imu/imu_krooz_sd_arch.h
@@ -0,0 +1,8 @@
+#ifndef IMU_KROOZ_SD_ARCH_H
+#define IMU_KROOZ_SD_ARCH_H
+
+#include "subsystems/imu.h"
+
+void imu_krooz_sd_arch_init(void);
+
+#endif /* IMU_KROOZ_SD_ARCH_H */
diff --git a/sw/airborne/boards/apogee_0.99.h b/sw/airborne/boards/apogee_0.99.h
index b73511266b..8a79bdc24b 100644
--- a/sw/airborne/boards/apogee_0.99.h
+++ b/sw/airborne/boards/apogee_0.99.h
@@ -60,6 +60,18 @@
#define UART6_GPIO_PORT_TX GPIOC
#define UART6_GPIO_TX GPIO6
+/* SPI */
+#define SPI1_GPIO_AF GPIO_AF5
+#define SPI1_GPIO_PORT_MISO GPIOA
+#define SPI1_GPIO_MISO GPIO6
+#define SPI1_GPIO_PORT_MOSI GPIOA
+#define SPI1_GPIO_MOSI GPIO7
+#define SPI1_GPIO_PORT_SCK GPIOA
+#define SPI1_GPIO_SCK GPIO5
+
+#define SPI_SELECT_SLAVE0_PORT GPIOB
+#define SPI_SELECT_SLAVE0_PIN GPIO9
+
/* Onboard ADCs */
#define USE_AD_TIM4 1
diff --git a/sw/airborne/boards/ardrone/at_com.h b/sw/airborne/boards/ardrone/at_com.h
index 431030eb31..f2b04185b2 100644
--- a/sw/airborne/boards/ardrone/at_com.h
+++ b/sw/airborne/boards/ardrone/at_com.h
@@ -178,7 +178,7 @@ typedef struct _navdata_gps_t {
uint8_t unk_2[16];
struct{
uint8_t sat;
- uint8_t unk;
+ uint8_t cn0;
}channels[12];
int32_t gps_plugged; /*!< When the gps is plugged */
uint8_t unk_3[108];
diff --git a/sw/airborne/boards/krooz/baro_board.c b/sw/airborne/boards/krooz/baro_board.c
new file mode 100644
index 0000000000..7b531ec97b
--- /dev/null
+++ b/sw/airborne/boards/krooz/baro_board.c
@@ -0,0 +1,32 @@
+
+#include "subsystems/sensors/baro.h"
+#include "baro_board.h"
+/*
+#include "subsystems/datalink/downlink.h"
+#include "mcu_periph/uart.h"
+#include "mcu_periph/sys_time.h"
+*/
+
+struct Baro baro;
+
+void baro_init(void) {
+ baro_ms5611_init();
+}
+
+void baro_periodic(void) {
+ static uint8_t cnt;
+ switch(cnt) {
+ case 0:
+ baro_ms5611_periodic();
+ cnt++;
+ break;
+ case 1:
+ baro_ms5611_d1();
+ cnt++;
+ break;
+ case 2:
+ baro_ms5611_d2();
+ cnt = 0;
+ break;
+ }
+}
diff --git a/sw/airborne/boards/krooz/baro_board.h b/sw/airborne/boards/krooz/baro_board.h
new file mode 100644
index 0000000000..b73f33d90d
--- /dev/null
+++ b/sw/airborne/boards/krooz/baro_board.h
@@ -0,0 +1,30 @@
+
+/*
+ * board specific fonctions for the KroozSD board
+ *
+ */
+
+#ifndef BOARDS_KROOZ_BARO_H
+#define BOARDS_KROOZ_BARO_H
+
+#include "std.h"
+#include "mcu_periph/i2c.h"
+#include "modules/sensors/baro_ms5611_i2c.h"
+#include "math/pprz_algebra_int.h"
+
+//#include "led.h"
+
+static inline void baro_event(void (*b_abs_handler)(void), void (*b_diff_handler)(void))
+{
+ baro_ms5611_event();
+ if(baro_ms5611_valid) {
+ baro.status = BS_RUNNING;
+ baro.absolute = (int32_t)baroms;
+ b_abs_handler();
+ baro_ms5611_valid = FALSE;
+ }
+}
+
+#define BaroEvent(_b_abs_handler, _b_diff_handler) baro_event(_b_abs_handler,_b_diff_handler)
+
+#endif /* BOARDS_KROOZ_SD_BARO_H */
diff --git a/sw/airborne/boards/krooz/imu_krooz.c b/sw/airborne/boards/krooz/imu_krooz.c
new file mode 100644
index 0000000000..3aad6a7803
--- /dev/null
+++ b/sw/airborne/boards/krooz/imu_krooz.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2013 Sergey Krukowski
+ *
+ * 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 boards/krooz/imu_krooz.c
+ *
+ * Driver for the IMU on the KroozSD board.
+ *
+ * Invensense MPU-6050
+ * Honeywell HMC-5883
+ */
+
+#include
+#include "boards/krooz/imu_krooz.h"
+#include "subsystems/imu/imu_krooz_sd_arch.h"
+#include "mcu_periph/i2c.h"
+#include "led.h"
+
+// Downlink
+#include "mcu_periph/uart.h"
+#include "messages.h"
+#include "subsystems/datalink/downlink.h"
+
+#ifndef DOWNLINK_DEVICE
+#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE
+#endif
+
+#if !defined KROOZ_LOWPASS_FILTER && !defined KROOZ_SMPLRT_DIV
+#define KROOZ_LOWPASS_FILTER MPU60X0_DLPF_256HZ
+#define KROOZ_SMPLRT_DIV 1
+#endif
+PRINT_CONFIG_VAR(KROOZ_SMPLRT_DIV)
+PRINT_CONFIG_VAR(KROOZ_LOWPASS_FILTER)
+
+#ifndef KROOZ_GYRO_RANGE
+#define KROOZ_GYRO_RANGE MPU60X0_GYRO_RANGE_250
+#endif
+PRINT_CONFIG_VAR(KROOZ_GYRO_RANGE)
+
+#ifndef KROOZ_ACCEL_RANGE
+#define KROOZ_ACCEL_RANGE MPU60X0_ACCEL_RANGE_2G
+#endif
+PRINT_CONFIG_VAR(KROOZ_ACCEL_RANGE)
+
+struct ImuKrooz imu_krooz;
+
+
+#if KROOZ_USE_MEDIAN_FILTER
+#include "filters/median_filter.h"
+struct MedianFilter3Int median_gyro, median_accel, median_mag;
+#endif
+
+void imu_impl_init( void )
+{
+ /////////////////////////////////////////////////////////////////////
+ // MPU-60X0
+ mpu60x0_i2c_init(&imu_krooz.mpu, &(IMU_KROOZ_I2C_DEV), MPU60X0_ADDR);
+ // change the default configuration
+ imu_krooz.mpu.config.smplrt_div = KROOZ_SMPLRT_DIV;
+ imu_krooz.mpu.config.dlpf_cfg = KROOZ_LOWPASS_FILTER;
+ imu_krooz.mpu.config.gyro_range = KROOZ_GYRO_RANGE;
+ imu_krooz.mpu.config.accel_range = KROOZ_ACCEL_RANGE;
+ imu_krooz.mpu.config.drdy_int_enable = TRUE;
+
+ hmc58xx_init(&imu_krooz.hmc, &(IMU_KROOZ_I2C_DEV), HMC58XX_ADDR);
+
+#if KROOZ_USE_MEDIAN_FILTER
+ // Init median filters
+ InitMedianFilterRatesInt(median_gyro);
+ InitMedianFilterVect3Int(median_accel);
+ InitMedianFilterVect3Int(median_mag);
+#endif
+
+ RATES_ASSIGN(imu_krooz.rates_sum, 0, 0, 0);
+ VECT3_ASSIGN(imu_krooz.accel_sum, 0, 0, 0);
+ imu_krooz.meas_nb = 0;
+
+ imu_krooz.gyr_valid = FALSE;
+ imu_krooz.acc_valid = FALSE;
+ imu_krooz.mag_valid = FALSE;
+
+ imu_krooz_sd_arch_init();
+}
+
+void imu_periodic( void )
+{
+ // Start reading the latest gyroscope data
+ if (!imu_krooz.mpu.config.initialized)
+ mpu60x0_i2c_start_configure(&imu_krooz.mpu);
+
+ if (!imu_krooz.hmc.initialized)
+ hmc58xx_start_configure(&imu_krooz.hmc);
+
+ if (imu_krooz.meas_nb) {
+ RATES_ASSIGN(imu.gyro_unscaled, imu_krooz.rates_sum.q / imu_krooz.meas_nb, imu_krooz.rates_sum.p / imu_krooz.meas_nb, imu_krooz.rates_sum.r / imu_krooz.meas_nb);
+#if KROOZ_USE_MEDIAN_FILTER
+ UpdateMedianFilterRatesInt(median_gyro, imu.gyro_unscaled);
+#endif
+ VECT3_ASSIGN(imu.accel_unscaled, imu_krooz.accel_sum.y / imu_krooz.meas_nb, imu_krooz.accel_sum.x / imu_krooz.meas_nb, imu_krooz.accel_sum.z / imu_krooz.meas_nb);
+#if KROOZ_USE_MEDIAN_FILTER
+ UpdateMedianFilterVect3Int(median_accel, imu.accel_unscaled);
+#endif
+ RATES_ASSIGN(imu_krooz.rates_sum, 0, 0, 0);
+ VECT3_ASSIGN(imu_krooz.accel_sum, 0, 0, 0);
+ imu_krooz.meas_nb = 0;
+
+ imu_krooz.gyr_valid = TRUE;
+ imu_krooz.acc_valid = TRUE;
+ }
+
+ //RunOnceEvery(10,imu_krooz_downlink_raw());
+}
+
+void imu_krooz_downlink_raw( void )
+{
+ DOWNLINK_SEND_IMU_GYRO_RAW(DefaultChannel, DefaultDevice,&imu.gyro_unscaled.p,&imu.gyro_unscaled.q,&imu.gyro_unscaled.r);
+ DOWNLINK_SEND_IMU_ACCEL_RAW(DefaultChannel, DefaultDevice,&imu.accel_unscaled.x,&imu.accel_unscaled.y,&imu.accel_unscaled.z);
+}
+
+
+void imu_krooz_event( void )
+{
+ // If the MPU6050 I2C transaction has succeeded: convert the data
+ mpu60x0_i2c_event(&imu_krooz.mpu);
+ if (imu_krooz.mpu.data_available) {
+ RATES_ADD(imu_krooz.rates_sum, imu_krooz.mpu.data_rates.rates);
+ VECT3_ADD(imu_krooz.accel_sum, imu_krooz.mpu.data_accel.vect);
+ imu_krooz.meas_nb++;
+ imu_krooz.mpu.data_available = FALSE;
+ }
+
+ // If the HMC5883 I2C transaction has succeeded: convert the data
+ hmc58xx_event(&imu_krooz.hmc);
+ if (imu_krooz.hmc.data_available) {
+ VECT3_COPY(imu.mag_unscaled, imu_krooz.hmc.data.vect);
+#if KROOZ_USE_MEDIAN_FILTER
+ UpdateMedianFilterVect3Int(median_mag, imu.mag_unscaled);
+#endif
+ imu_krooz.hmc.data_available = FALSE;
+ imu_krooz.mag_valid = TRUE;
+ }
+}
diff --git a/sw/airborne/boards/krooz/imu_krooz.h b/sw/airborne/boards/krooz/imu_krooz.h
new file mode 100644
index 0000000000..74afaf00f3
--- /dev/null
+++ b/sw/airborne/boards/krooz/imu_krooz.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013 Sergey Krukowski
+ *
+ * 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 boards/krooz/imu_krooz.h
+ *
+ * Driver for the IMU on the KroozSD board.
+ *
+ * Invensense MPU-6050
+ */
+
+#ifndef IMU_KROOZ_H
+#define IMU_KROOZ_H
+
+#include "std.h"
+#include "generated/airframe.h"
+#include "subsystems/imu.h"
+
+#include "peripherals/mpu60x0_i2c.h"
+#include "peripherals/hmc58xx.h"
+
+// Default configuration
+#if !defined IMU_GYRO_P_SIGN & !defined IMU_GYRO_Q_SIGN & !defined IMU_GYRO_R_SIGN
+#define IMU_GYRO_P_SIGN -1
+#define IMU_GYRO_Q_SIGN 1
+#define IMU_GYRO_R_SIGN 1
+#endif
+#if !defined IMU_ACCEL_X_SIGN & !defined IMU_ACCEL_Y_SIGN & !defined IMU_ACCEL_Z_SIGN
+#define IMU_ACCEL_X_SIGN -1
+#define IMU_ACCEL_Y_SIGN 1
+#define IMU_ACCEL_Z_SIGN 1
+#endif
+#if !defined IMU_MAG_X_SIGN & !defined IMU_MAG_Y_SIGN & !defined IMU_MAG_Z_SIGN
+#define IMU_MAG_X_SIGN 1
+#define IMU_MAG_Y_SIGN 1
+#define IMU_MAG_Z_SIGN 1
+#endif
+
+/** default gyro sensitivy and neutral from the datasheet
+ * MPU with 250 deg/s has 131.072 LSB/(deg/s)
+ * sens = 1/131.072 * pi/180 * 2^INT32_RATE_FRAC
+ * sens = 1/131.072 * pi/180 * 4096 = 0.5454
+ I*/
+#if !defined IMU_GYRO_P_SENS & !defined IMU_GYRO_Q_SENS & !defined IMU_GYRO_R_SENS
+// FIXME
+#define IMU_GYRO_P_SENS 0.5454
+#define IMU_GYRO_P_SENS_NUM 2727
+#define IMU_GYRO_P_SENS_DEN 5000
+#define IMU_GYRO_Q_SENS 0.5454
+#define IMU_GYRO_Q_SENS_NUM 2727
+#define IMU_GYRO_Q_SENS_DEN 5000
+#define IMU_GYRO_R_SENS 0.5454
+#define IMU_GYRO_R_SENS_NUM 2727
+#define IMU_GYRO_R_SENS_DEN 5000
+#endif
+#if !defined IMU_GYRO_P_NEUTRAL & !defined IMU_GYRO_Q_NEUTRAL & !defined IMU_GYRO_R_NEUTRAL
+#define IMU_GYRO_P_NEUTRAL 0
+#define IMU_GYRO_Q_NEUTRAL 0
+#define IMU_GYRO_R_NEUTRAL 0
+#endif
+
+
+/** default accel sensitivy from the datasheet
+ * MPU with 2g has 16384 LSB/g
+ * sens = 9.81 [m/s^2] / 16384 [LSB/g] * 2^INT32_ACCEL_FRAC = 0.6131
+ */
+#if !defined IMU_ACCEL_X_SENS & !defined IMU_ACCEL_Y_SENS & !defined IMU_ACCEL_Z_SENS
+// FIXME
+#define IMU_ACCEL_X_SENS 0.6131
+#define IMU_ACCEL_X_SENS_NUM 6131
+#define IMU_ACCEL_X_SENS_DEN 10000
+#define IMU_ACCEL_Y_SENS 0.6131
+#define IMU_ACCEL_Y_SENS_NUM 6131
+#define IMU_ACCEL_Y_SENS_DEN 10000
+#define IMU_ACCEL_Z_SENS 0.6131
+#define IMU_ACCEL_Z_SENS_NUM 6131
+#define IMU_ACCEL_Z_SENS_DEN 10000
+#endif
+#if !defined IMU_ACCEL_X_NEUTRAL & !defined IMU_ACCEL_Y_NEUTRAL & !defined IMU_ACCEL_Z_NEUTRAL
+#define IMU_ACCEL_X_NEUTRAL 0
+#define IMU_ACCEL_Y_NEUTRAL 0
+#define IMU_ACCEL_Z_NEUTRAL 0
+#endif
+
+struct ImuKrooz {
+ volatile bool_t gyr_valid;
+ volatile bool_t acc_valid;
+ volatile bool_t mag_valid;
+ struct Mpu60x0_I2c mpu;
+ struct Hmc58xx hmc;
+ struct Int32Rates rates_sum;
+ struct Int32Vect3 accel_sum;
+ volatile uint8_t meas_nb;
+};
+
+extern struct ImuKrooz imu_krooz;
+
+
+/* must be defined in order to be IMU code: declared in imu.h
+extern void imu_impl_init(void);
+extern void imu_periodic(void);
+*/
+
+/* Own Extra Functions */
+extern void imu_krooz_event( void );
+extern void imu_krooz_downlink_raw( void );
+
+static inline void ImuEvent(void (* _gyro_handler)(void), void (* _accel_handler)(void), void (* _mag_handler)(void) __attribute__((unused))) {
+ imu_krooz_event();
+ if (imu_krooz.gyr_valid) {
+ imu_krooz.gyr_valid = FALSE;
+ _gyro_handler();
+ }
+ if (imu_krooz.acc_valid) {
+ imu_krooz.acc_valid = FALSE;
+ _accel_handler();
+ }
+ if (imu_krooz.mag_valid) {
+ imu_krooz.mag_valid = FALSE;
+ _mag_handler();
+ }
+}
+
+#endif // IMU_KROOZ_H
diff --git a/sw/airborne/boards/krooz_sd.h b/sw/airborne/boards/krooz_sd.h
index d4fb6deab1..dc24cbda4a 100644
--- a/sw/airborne/boards/krooz_sd.h
+++ b/sw/airborne/boards/krooz_sd.h
@@ -1,5 +1,5 @@
-#ifndef CONFIG_KROOZ_1_0_H
-#define CONFIG_KROOZ_1_0_H
+#ifndef CONFIG_KROOZ_SD_H
+#define CONFIG_KROOZ_SD_H
#define BOARD_KROOZ
@@ -99,6 +99,29 @@
#define UART5_GPIO_PORT_TX GPIOC
#define UART5_GPIO_TX GPIO12
+/* SPI */
+#define SPI1_GPIO_AF GPIO_AF5
+#define SPI1_GPIO_PORT_MISO GPIOA
+#define SPI1_GPIO_MISO GPIO6
+#define SPI1_GPIO_PORT_MOSI GPIOA
+#define SPI1_GPIO_MOSI GPIO7
+#define SPI1_GPIO_PORT_SCK GPIOA
+#define SPI1_GPIO_SCK GPIO5
+
+#define SPI2_GPIO_AF GPIO_AF5
+#define SPI2_GPIO_PORT_MISO GPIOB
+#define SPI2_GPIO_MISO GPIO14
+#define SPI2_GPIO_PORT_MOSI GPIOB
+#define SPI2_GPIO_MOSI GPIO15
+#define SPI2_GPIO_PORT_SCK GPIOB
+#define SPI2_GPIO_SCK GPIO13
+
+#define SPI_SELECT_SLAVE0_PORT GPIOA
+#define SPI_SELECT_SLAVE0_PIN GPIO4
+#define SPI_SELECT_SLAVE1_PORT GPIOB
+#define SPI_SELECT_SLAVE1_PIN GPIO12
+#define SPI_SELECT_SLAVE2_PORT GPIOB
+#define SPI_SELECT_SLAVE2_PIN GPIO2
/* I2C mapping */
#define I2C1_GPIO_PORT GPIOB
@@ -109,6 +132,10 @@
#define I2C2_GPIO_SCL GPIO10
#define I2C2_GPIO_SDA GPIO11
+#define I2C3_GPIO_PORT_SCL GPIOA
+#define I2C3_GPIO_PORT_SDA GPIOC
+#define I2C3_GPIO_SCL GPIO8
+#define I2C3_GPIO_SDA GPIO9
/* Onboard ADCs */
#define USE_AD_TIM1 1
@@ -197,20 +224,10 @@
}
#endif // USE_AD1
-
-/* I2C mapping */
-#define GPIO_I2C1_SCL GPIO8
-#define GPIO_I2C1_SDA GPIO9
-#define GPIO_I2C2_SCL GPIO10
-#define GPIO_I2C2_SDA GPIO11
-#define GPIO_I2C3_SCL GPIO8 //PA8
-#define GPIO_I2C3_SDA GPIO9 //PC9
-
/* Activate onboard baro */
#define BOARD_HAS_BARO 1
/* PWM */
-//#define PWM_USE_TIM2 1
#define PWM_USE_TIM3 1
#define PWM_USE_TIM4 1
#define PWM_USE_TIM5 1
@@ -227,18 +244,23 @@
#define USE_PWM9 1
//#define USE_PWM10 1
+#if USE_PWM10
+#define ACTUATORS_PWM_NB 11
+#define PWM_USE_TIM2 1
+#else
#define ACTUATORS_PWM_NB 10
+#endif
// PWM_SERVO_x is the index of the servo in the actuators_pwm_values array
#if USE_PWM0
#define PWM_SERVO_0 0
#define PWM_SERVO_0_TIMER TIM3
-#define PWM_SERVO_0_RCC_IOP RCC_AHB1ENR_IOPCEN
-#define PWM_SERVO_0_GPIO GPIOC
-#define PWM_SERVO_0_PIN GPIO6
-#define PWM_SERVO_0_AF GPIO_AF1
-#define PWM_SERVO_0_OC TIM_OC1
-#define PWM_SERVO_0_OC_BIT (1<<0)
+#define PWM_SERVO_0_RCC_IOP RCC_AHB1ENR_IOPBEN
+#define PWM_SERVO_0_GPIO GPIOB
+#define PWM_SERVO_0_PIN GPIO1
+#define PWM_SERVO_0_AF GPIO_AF2
+#define PWM_SERVO_0_OC TIM_OC4
+#define PWM_SERVO_0_OC_BIT (1<<3)
#else
#define PWM_SERVO_0_OC_BIT 0
#endif
@@ -248,10 +270,10 @@
#define PWM_SERVO_1_TIMER TIM3
#define PWM_SERVO_1_RCC_IOP RCC_AHB1ENR_IOPCEN
#define PWM_SERVO_1_GPIO GPIOC
-#define PWM_SERVO_1_PIN GPIO7
-#define PWM_SERVO_1_AF GPIO_AF1
-#define PWM_SERVO_1_OC TIM_OC2
-#define PWM_SERVO_1_OC_BIT (1<<1)
+#define PWM_SERVO_1_PIN GPIO8
+#define PWM_SERVO_1_AF GPIO_AF2
+#define PWM_SERVO_1_OC TIM_OC3
+#define PWM_SERVO_1_OC_BIT (1<<2)
#else
#define PWM_SERVO_1_OC_BIT 0
#endif
@@ -261,23 +283,23 @@
#define PWM_SERVO_2_TIMER TIM3
#define PWM_SERVO_2_RCC_IOP RCC_AHB1ENR_IOPCEN
#define PWM_SERVO_2_GPIO GPIOC
-#define PWM_SERVO_2_PIN GPIO8
-#define PWM_SERVO_2_AF GPIO_AF1
-#define PWM_SERVO_2_OC TIM_OC3
-#define PWM_SERVO_2_OC_BIT (1<<2)
+#define PWM_SERVO_2_PIN GPIO7
+#define PWM_SERVO_2_AF GPIO_AF2
+#define PWM_SERVO_2_OC TIM_OC2
+#define PWM_SERVO_2_OC_BIT (1<<1)
#else
#define PWM_SERVO_2_OC_BIT 0
#endif
#if USE_PWM3
-#define PWM_SERVO_3_IDX 3
+#define PWM_SERVO_3 3
#define PWM_SERVO_3_TIMER TIM3
-#define PWM_SERVO_3_RCC_IOP RCC_AHB1ENR_IOPCEN
-#define PWM_SERVO_3_GPIO GPIOC
-#define PWM_SERVO_3_PIN GPIO9
-#define PWM_SERVO_3_AF GPIO_AF1
-#define PWM_SERVO_3_OC TIM_OC4
-#define PWM_SERVO_3_OC_BIT (1<<3)
+#define PWM_SERVO_3_RCC_IOP RCC_AHB1ENR_IOPBEN
+#define PWM_SERVO_3_GPIO GPIOB
+#define PWM_SERVO_3_PIN GPIO4
+#define PWM_SERVO_3_AF GPIO_AF2
+#define PWM_SERVO_3_OC TIM_OC1
+#define PWM_SERVO_3_OC_BIT (1<<0)
#else
#define PWM_SERVO_3_OC_BIT 0
#endif
@@ -287,10 +309,10 @@
#define PWM_SERVO_4_TIMER TIM4
#define PWM_SERVO_4_RCC_IOP RCC_AHB1ENR_IOPBEN
#define PWM_SERVO_4_GPIO GPIOB
-#define PWM_SERVO_4_PIN GPIO6
-#define PWM_SERVO_4_AF GPIO_AF1
-#define PWM_SERVO_4_OC TIM_OC1
-#define PWM_SERVO_4_OC_BIT (1<<0)
+#define PWM_SERVO_4_PIN GPIO7
+#define PWM_SERVO_4_AF GPIO_AF2
+#define PWM_SERVO_4_OC TIM_OC2
+#define PWM_SERVO_4_OC_BIT (1<<1)
#else
#define PWM_SERVO_4_OC_BIT 0
#endif
@@ -300,10 +322,10 @@
#define PWM_SERVO_5_TIMER TIM4
#define PWM_SERVO_5_RCC_IOP RCC_AHB1ENR_IOPBEN
#define PWM_SERVO_5_GPIO GPIOB
-#define PWM_SERVO_5_PIN GPIO7
-#define PWM_SERVO_5_AF GPIO_AF1
-#define PWM_SERVO_5_OC TIM_OC2
-#define PWM_SERVO_5_OC_BIT (1<<1)
+#define PWM_SERVO_5_PIN GPIO6
+#define PWM_SERVO_5_AF GPIO_AF2
+#define PWM_SERVO_5_OC TIM_OC1
+#define PWM_SERVO_5_OC_BIT (1<<0)
#else
#define PWM_SERVO_5_OC_BIT 0
#endif
@@ -313,10 +335,10 @@
#define PWM_SERVO_6_TIMER TIM5
#define PWM_SERVO_6_RCC_IOP RCC_AHB1ENR_IOPAEN
#define PWM_SERVO_6_GPIO GPIOA
-#define PWM_SERVO_6_PIN GPIO0
-#define PWM_SERVO_6_AF GPIO_AF1
-#define PWM_SERVO_6_OC TIM_OC1
-#define PWM_SERVO_6_OC_BIT (1<<0)
+#define PWM_SERVO_6_PIN GPIO3
+#define PWM_SERVO_6_AF GPIO_AF2
+#define PWM_SERVO_6_OC TIM_OC4
+#define PWM_SERVO_6_OC_BIT (1<<3)
#else
#define PWM_SERVO_6_OC_BIT 0
#endif
@@ -326,10 +348,10 @@
#define PWM_SERVO_7_TIMER TIM5
#define PWM_SERVO_7_RCC_IOP RCC_AHB1ENR_IOPAEN
#define PWM_SERVO_7_GPIO GPIOA
-#define PWM_SERVO_7_PIN GPIO1
-#define PWM_SERVO_7_AF GPIO_AF1
-#define PWM_SERVO_7_OC TIM_OC2
-#define PWM_SERVO_7_OC_BIT (1<<1)
+#define PWM_SERVO_7_PIN GPIO2
+#define PWM_SERVO_7_AF GPIO_AF2
+#define PWM_SERVO_7_OC TIM_OC3
+#define PWM_SERVO_7_OC_BIT (1<<2)
#else
#define PWM_SERVO_7_OC_BIT 0
#endif
@@ -339,10 +361,10 @@
#define PWM_SERVO_8_TIMER TIM5
#define PWM_SERVO_8_RCC_IOP RCC_AHB1ENR_IOPAEN
#define PWM_SERVO_8_GPIO GPIOA
-#define PWM_SERVO_8_PIN GPIO2
-#define PWM_SERVO_8_AF GPIO_AF1
-#define PWM_SERVO_8_OC TIM_OC3
-#define PWM_SERVO_8_OC_BIT (1<<2)
+#define PWM_SERVO_8_PIN GPIO1
+#define PWM_SERVO_8_AF GPIO_AF2
+#define PWM_SERVO_8_OC TIM_OC2
+#define PWM_SERVO_8_OC_BIT (1<<1)
#else
#define PWM_SERVO_8_OC_BIT 0
#endif
@@ -352,10 +374,10 @@
#define PWM_SERVO_9_TIMER TIM5
#define PWM_SERVO_9_RCC_IOP RCC_AHB1ENR_IOPAEN
#define PWM_SERVO_9_GPIO GPIOA
-#define PWM_SERVO_9_PIN GPIO3
-#define PWM_SERVO_9_AF GPIO_AF1
-#define PWM_SERVO_9_OC TIM_OC4
-#define PWM_SERVO_9_OC_BIT (1<<3)
+#define PWM_SERVO_9_PIN GPIO0
+#define PWM_SERVO_9_AF GPIO_AF2
+#define PWM_SERVO_9_OC TIM_OC1
+#define PWM_SERVO_9_OC_BIT (1<<0)
#else
#define PWM_SERVO_9_OC_BIT 0
#endif
@@ -397,7 +419,7 @@
* Spektrum
*/
/* The line that is pulled low at power up to initiate the bind process */
-#define SPEKTRUM_BIND_PIN GPIO8
+#define SPEKTRUM_BIND_PIN GPIO9
#define SPEKTRUM_BIND_PIN_PORT GPIOA
-#endif /* CONFIG_KROOZ_1_0_H */
+#endif /* CONFIG_KROOZ_SD_H */
diff --git a/sw/airborne/firmwares/rotorcraft/autopilot.c b/sw/airborne/firmwares/rotorcraft/autopilot.c
index 2b816e0625..ba54e696a4 100644
--- a/sw/airborne/firmwares/rotorcraft/autopilot.c
+++ b/sw/airborne/firmwares/rotorcraft/autopilot.c
@@ -65,6 +65,7 @@ static inline int ahrs_is_aligned(void) {
return (ahrs.status == AHRS_RUNNING);
}
#else
+PRINT_CONFIG_MSG("Using AUTOPILOT_DISABLE_AHRS_KILL")
static inline int ahrs_is_aligned(void) {
return TRUE;
}
@@ -80,7 +81,7 @@ static inline int ahrs_is_aligned(void) {
#ifndef MODE_STARTUP
#define MODE_STARTUP AP_MODE_KILL
-PRINT_CONFIG_MSG("Using AP_MODE_KILL as MODE_STARTUP")
+PRINT_CONFIG_MSG("Using default AP_MODE_KILL as MODE_STARTUP")
#endif
static void send_alive(void) {
@@ -173,7 +174,8 @@ static void send_baro_raw(void) {
}
void autopilot_init(void) {
- autopilot_mode = MODE_STARTUP;
+ /* mode is finally set at end of init if MODE_STARTUP is not KILL */
+ autopilot_mode = AP_MODE_KILL;
autopilot_motors_on = FALSE;
kill_throttle = ! autopilot_motors_on;
autopilot_in_flight = FALSE;
@@ -187,8 +189,17 @@ void autopilot_init(void) {
#ifdef POWER_SWITCH_LED
LED_ON(POWER_SWITCH_LED); // POWER OFF
#endif
+
autopilot_arming_init();
+ nav_init();
+ guidance_h_init();
+ guidance_v_init();
+ stabilization_init();
+
+ /* set startup mode, propagats through to guidance h/v */
+ autopilot_set_mode(MODE_STARTUP);
+
register_periodic_telemetry(DefaultPeriodic, "ALIVE", send_alive);
register_periodic_telemetry(DefaultPeriodic, "ROTORCRAFT_STATUS", send_status);
register_periodic_telemetry(DefaultPeriodic, "ROTORCRAFT_FP", send_fp);
diff --git a/sw/airborne/firmwares/rotorcraft/main.c b/sw/airborne/firmwares/rotorcraft/main.c
index c0fe0297f8..a1ed2a3c64 100644
--- a/sw/airborne/firmwares/rotorcraft/main.c
+++ b/sw/airborne/firmwares/rotorcraft/main.c
@@ -140,11 +140,6 @@ STATIC_INLINE void main_init( void ) {
baro_init();
imu_init();
- autopilot_init();
- nav_init();
- guidance_h_init();
- guidance_v_init();
- stabilization_init();
ahrs_aligner_init();
ahrs_init();
@@ -155,6 +150,8 @@ STATIC_INLINE void main_init( void ) {
gps_init();
#endif
+ autopilot_init();
+
modules_init();
settings_init();
@@ -227,6 +224,7 @@ STATIC_INLINE void failsafe_check( void ) {
#if USE_GPS
if (autopilot_mode == AP_MODE_NAV &&
+ autopilot_motors_on &&
#if NO_GPS_LOST_WITH_RC_VALID
radio_control.status != RC_OK &&
#endif
diff --git a/sw/airborne/modules/digital_cam/led_cam_ctrl.c b/sw/airborne/modules/digital_cam/led_cam_ctrl.c
index 8928381f48..81b701f6af 100644
--- a/sw/airborne/modules/digital_cam/led_cam_ctrl.c
+++ b/sw/airborne/modules/digital_cam/led_cam_ctrl.c
@@ -52,6 +52,12 @@ void dc_send_command(uint8_t cmd)
case DC_ON:
DC_PUSH(DC_POWER_LED);
break;
+#endif
+#ifdef DC_POWER_OFF_LED
+ case DC_OFF:
+ DC_PUSH(DC_POWER_OFF_LED);
+ dc_timer = DC_POWER_OFF_DELAY;
+ break;
#endif
default:
break;
diff --git a/sw/airborne/modules/digital_cam/led_cam_ctrl.h b/sw/airborne/modules/digital_cam/led_cam_ctrl.h
index 37eb0a7f17..fde5cb4aa7 100644
--- a/sw/airborne/modules/digital_cam/led_cam_ctrl.h
+++ b/sw/airborne/modules/digital_cam/led_cam_ctrl.h
@@ -35,6 +35,7 @@
*
*
*
+ *
* @endverbatim
* Related bank and pin must also be defined:
* @verbatim
@@ -68,6 +69,10 @@ extern uint8_t dc_timer;
#define DC_SHUTTER_DELAY 2 /* 4Hz -> 0.5s */
#endif
+#ifndef DC_POWER_OFF_DELAY
+#define DC_POWER_OFF_DELAY 3
+#endif
+
#ifndef DC_SHUTTER_LED
#error DC: Please specify at least a SHUTTER LED
#endif
@@ -90,6 +95,9 @@ static inline void led_cam_ctrl_init(void)
#ifdef DC_POWER_LED
DC_RELEASE(DC_POWER_LED);
#endif
+#ifdef DC_POWER_OFF_LED
+ DC_RELEASE(DC_POWER_OFF_LED);
+#endif
}
@@ -114,6 +122,9 @@ static inline void led_cam_ctrl_periodic( void )
#endif
#ifdef DC_POWER_LED
DC_RELEASE(DC_POWER_LED);
+#endif
+#ifdef DC_POWER_OFF_LED
+ DC_RELEASE(DC_POWER_OFF_LED);
#endif
}
diff --git a/sw/airborne/modules/sensors/airspeed_ets.c b/sw/airborne/modules/sensors/airspeed_ets.c
index 706904d3bb..15eff2ce56 100644
--- a/sw/airborne/modules/sensors/airspeed_ets.c
+++ b/sw/airborne/modules/sensors/airspeed_ets.c
@@ -42,13 +42,14 @@
#include "state.h"
#include "mcu_periph/i2c.h"
#include "mcu_periph/uart.h"
+#include "mcu_periph/sys_time.h"
#include "messages.h"
#include "subsystems/datalink/downlink.h"
#include
#if !USE_AIRSPEED
-#ifndef SENSOR_SYNC_SEND
-#warning either set USE_AIRSPEED or SENSOR_SYNC_SEND to use ets_airspeed
+#ifndef AIRSPEED_ETS_SYNC_SEND
+#warning either set USE_AIRSPEED or AIRSPEED_ETS_SYNC_SEND to use ets_airspeed
#endif
#endif
@@ -68,6 +69,13 @@
#ifndef AIRSPEED_ETS_I2C_DEV
#define AIRSPEED_ETS_I2C_DEV i2c0
#endif
+PRINT_CONFIG_VAR(AIRSPEED_ETS_I2C_DEV)
+
+/** delay in seconds until sensor is read after startup */
+#ifndef AIRSPEED_ETS_START_DELAY
+#define AIRSPEED_ETS_START_DELAY 0.2
+#endif
+PRINT_CONFIG_VAR(AIRSPEED_ETS_START_DELAY)
// Global variables
@@ -85,6 +93,8 @@ volatile bool_t airspeed_ets_i2c_done;
bool_t airspeed_ets_offset_init;
uint32_t airspeed_ets_offset_tmp;
uint16_t airspeed_ets_cnt;
+uint32_t airspeed_ets_delay_time;
+bool_t airspeed_ets_delay_done;
void airspeed_ets_init( void ) {
int n;
@@ -93,7 +103,7 @@ void airspeed_ets_init( void ) {
airspeed_ets_offset = 0;
airspeed_ets_offset_tmp = 0;
airspeed_ets_i2c_done = TRUE;
- airspeed_ets_valid = TRUE;
+ airspeed_ets_valid = FALSE;
airspeed_ets_offset_init = FALSE;
airspeed_ets_cnt = AIRSPEED_ETS_OFFSET_NBSAMPLES_INIT + AIRSPEED_ETS_OFFSET_NBSAMPLES_AVRG;
@@ -102,10 +112,17 @@ void airspeed_ets_init( void ) {
airspeed_ets_buffer[n] = 0.0;
airspeed_ets_i2c_trans.status = I2CTransDone;
+
+ airspeed_ets_delay_done = FALSE;
+ SysTimeTimerStart(airspeed_ets_delay_time);
}
void airspeed_ets_read_periodic( void ) {
#ifndef SITL
+ if (!airspeed_ets_delay_done) {
+ if (SysTimeTimer(airspeed_ets_delay_time) < USEC_OF_SEC(AIRSPEED_ETS_START_DELAY)) return;
+ else airspeed_ets_delay_done = TRUE;
+ }
if (airspeed_ets_i2c_trans.status == I2CTransDone)
i2c_receive(&AIRSPEED_ETS_I2C_DEV, &airspeed_ets_i2c_trans, AIRSPEED_ETS_ADDR, 2);
#else // SITL
@@ -170,7 +187,7 @@ void airspeed_ets_read_event( void ) {
#if USE_AIRSPEED
stateSetAirspeed_f(&airspeed_ets);
#endif
-#ifdef SENSOR_SYNC_SEND
+#ifdef AIRSPEED_ETS_SYNC_SEND
DOWNLINK_SEND_AIRSPEED_ETS(DefaultChannel, DefaultDevice, &airspeed_ets_raw, &airspeed_ets_offset, &airspeed_ets);
#endif
} else {
diff --git a/sw/airborne/modules/sensors/baro_amsys.c b/sw/airborne/modules/sensors/baro_amsys.c
index a3e23c62c7..8160c89672 100644
--- a/sw/airborne/modules/sensors/baro_amsys.c
+++ b/sw/airborne/modules/sensors/baro_amsys.c
@@ -45,12 +45,21 @@
#define BARO_AMSYS_ADDR 0xE4
#define BARO_AMSYS_REG 0x07
-#define BARO_AMSYS_SCALE 0.32
+#ifndef BARO_AMSYS_SCALE
+#define BARO_AMSYS_SCALE 1
+#endif
+#ifndef BARO_AMSYS_MAX_PRESSURE
#define BARO_AMSYS_MAX_PRESSURE 103400 // Pascal
+#endif
#define BARO_AMSYS_OFFSET_MAX 29491
#define BARO_AMSYS_OFFSET_MIN 3277
#define BARO_AMSYS_OFFSET_NBSAMPLES_INIT 40
#define BARO_AMSYS_OFFSET_NBSAMPLES_AVRG 60
+#ifndef BARO_AMSYS_FILTER
+#define BARO_AMSYS_FILTER 0
+#endif
+#define BARO_AMSYS_R 0.5
+#define BARO_AMSYS_SIGMA2 0.1
#ifdef MEASURE_AMSYS_TEMPERATURE
#define TEMPERATURE_AMSYS_OFFSET_MAX 29491
@@ -59,8 +68,6 @@
#define TEMPERATURE_AMSYS_MIN -25
#endif
-//#define BARO_AMSYS_R 0.5
-//#define BARO_AMSYS_SIGMA2 0.1
//#define BARO_ALT_CORRECTION 0.0
#ifndef BARO_AMSYS_I2C_DEV
#define BARO_AMSYS_I2C_DEV i2c0
@@ -73,17 +80,18 @@ uint16_t baro_amsys_adc;
float baro_amsys_offset;
bool_t baro_amsys_valid;
float baro_amsys_altitude;
+bool_t baro_amsys_enabled;
+float baro_amsys_r;
+float baro_amsys_sigma2;
float baro_amsys_temp;
float baro_amsys_p;
float baro_amsys_offset_altitude;
float baro_amsys_abs_altitude;
float ref_alt_init; //Altitude by initialising
+float baro_scale;
float baro_filter;
float baro_old;
-//float baro_amsys_r;
-//float baro_amsys_sigma2;
-
struct i2c_transaction baro_amsys_i2c_trans;
@@ -93,106 +101,112 @@ double baro_amsys_offset_tmp;
uint16_t baro_amsys_cnt;
void baro_amsys_init( void ) {
- baro_filter=BARO_FILTER;
- pBaroRaw = 0;
- tBaroRaw = 0;
- baro_amsys_altitude = 0.0;
- baro_amsys_p=0.0;
- baro_amsys_offset = 0;
- baro_amsys_offset_tmp = 0;
- baro_amsys_valid = TRUE;
- baro_amsys_offset_init = FALSE;
-// baro_amsys_enabled = TRUE;
- baro_amsys_cnt = BARO_AMSYS_OFFSET_NBSAMPLES_INIT + BARO_AMSYS_OFFSET_NBSAMPLES_AVRG;
-// baro_amsys_r = BARO_AMSYS_R;
-// baro_amsys_sigma2 = BARO_AMSYS_SIGMA2;
-// baro_head=0;
- ref_alt_init = 0;
- baro_amsys_i2c_trans.status = I2CTransDone;
+ baro_filter=BARO_AMSYS_FILTER;
+ pBaroRaw = 0;
+ tBaroRaw = 0;
+ baro_amsys_altitude = 0.0;
+ baro_amsys_p=0.0;
+ baro_amsys_offset = 0;
+ baro_amsys_offset_tmp = 0;
+ baro_amsys_valid = TRUE;
+ baro_amsys_offset_init = FALSE;
+ baro_amsys_enabled = TRUE;
+ baro_scale = BARO_AMSYS_SCALE;
+ baro_amsys_cnt = BARO_AMSYS_OFFSET_NBSAMPLES_INIT + BARO_AMSYS_OFFSET_NBSAMPLES_AVRG;
+ baro_amsys_r = BARO_AMSYS_R;
+ baro_amsys_sigma2 = BARO_AMSYS_SIGMA2;
+ // baro_head=0;
+ ref_alt_init = 0;
+ baro_amsys_i2c_trans.status = I2CTransDone;
}
void baro_amsys_read_periodic( void ) {
// Initiate next read
#ifndef SITL
- if (baro_amsys_i2c_trans.status == I2CTransDone){
+ if (baro_amsys_i2c_trans.status == I2CTransDone){
#ifndef MEASURE_AMSYS_TEMPERATURE
- i2c_receive(&BARO_AMSYS_I2C_DEV, &baro_amsys_i2c_trans, BARO_AMSYS_ADDR, 2);
+ i2c_receive(&BARO_AMSYS_I2C_DEV, &baro_amsys_i2c_trans, BARO_AMSYS_ADDR, 2);
#else
- i2c_receive(&BARO_AMSYS_I2C_DEV, &baro_amsys_i2c_trans, BARO_AMSYS_ADDR, 4);
+ i2c_receive(&BARO_AMSYS_I2C_DEV, &baro_amsys_i2c_trans, BARO_AMSYS_ADDR, 4);
#endif
- }
+ }
#else // SITL
- pBaroRaw = 0;
- baro_amsys_altitude = gps.hmsl / 1000.0;
- baro_amsys_adc = baro_amsys_altitude / BARO_AMSYS_SCALE;
- baro_amsys_valid = TRUE;
+ /* fake an offset so sim works for under hmsl as well */
+ if (!baro_amsys_offset_init) {
+ baro_amsys_offset = BARO_AMSYS_OFFSET_MAX;
+ baro_amsys_offset_init = TRUE;
+ }
+ pBaroRaw = 0;
+ baro_amsys_altitude = gps.hmsl / 1000.0;
+ baro_amsys_adc = baro_amsys_offset - ((baro_amsys_altitude - ground_alt) / INS_BARO_SENS);
+ baro_amsys_valid = TRUE;
+#endif
+
+#ifdef BARO_AMSYS_SYNC_SEND
+ DOWNLINK_SEND_AMSYS_BARO(DefaultChannel, DefaultDevice, &pBaroRaw, &baro_amsys_p, &baro_amsys_offset, &ref_alt_init, &baro_amsys_abs_altitude, &baro_amsys_altitude, &baro_amsys_temp);
+#else
+ RunOnceEvery(10, DOWNLINK_SEND_AMSYS_BARO(DefaultChannel, DefaultDevice, &pBaroRaw, &baro_amsys_p, &baro_amsys_offset, &ref_alt_init, &baro_amsys_abs_altitude, &baro_amsys_altitude, &baro_amsys_temp));
#endif
}
void baro_amsys_read_event( void ) {
- pBaroRaw = 0;
- // Get raw altimeter from buffer
- pBaroRaw = (baro_amsys_i2c_trans.buf[0] << 8) | baro_amsys_i2c_trans.buf[1];
+ pBaroRaw = 0;
+ // Get raw altimeter from buffer
+ pBaroRaw = (baro_amsys_i2c_trans.buf[0] << 8) | baro_amsys_i2c_trans.buf[1];
#ifdef MEASURE_AMSYS_TEMPERATURE
- tBaroRaw = (baro_amsys_i2c_trans.buf[2] << 8) | baro_amsys_i2c_trans.buf[3];
- baro_amsys_temp = (float)(tBaroRaw-TEMPERATURE_AMSYS_OFFSET_MIN)*TEMPERATURE_AMSYS_MAX/(float)(TEMPERATURE_AMSYS_OFFSET_MAX-TEMPERATURE_AMSYS_OFFSET_MIN)+(float)TEMPERATURE_AMSYS_MIN;
+ tBaroRaw = (baro_amsys_i2c_trans.buf[2] << 8) | baro_amsys_i2c_trans.buf[3];
+ baro_amsys_temp = (float)(tBaroRaw-TEMPERATURE_AMSYS_OFFSET_MIN)*TEMPERATURE_AMSYS_MAX/(float)(TEMPERATURE_AMSYS_OFFSET_MAX-TEMPERATURE_AMSYS_OFFSET_MIN)+(float)TEMPERATURE_AMSYS_MIN;
#endif
- // Check if this is valid altimeter
- if (pBaroRaw == 0)
- baro_amsys_valid = FALSE;
- else
- baro_amsys_valid = TRUE;
+ // Check if this is valid altimeter
+ if (pBaroRaw == 0)
+ baro_amsys_valid = FALSE;
+ else
+ baro_amsys_valid = TRUE;
baro_amsys_adc = pBaroRaw;
- // Continue only if a new altimeter value was received
- //if (baro_amsys_valid && GpsFixValid()) {
- if (baro_amsys_valid) {
- //Cut RAW Min and Max
- if (pBaroRaw < BARO_AMSYS_OFFSET_MIN)
- pBaroRaw = BARO_AMSYS_OFFSET_MIN;
- if (pBaroRaw > BARO_AMSYS_OFFSET_MAX)
- pBaroRaw = BARO_AMSYS_OFFSET_MAX;
+ // Continue only if a new altimeter value was received
+ //if (baro_amsys_valid && GpsFixValid()) {
+ if (baro_amsys_valid) {
+ //Cut RAW Min and Max
+ if (pBaroRaw < BARO_AMSYS_OFFSET_MIN)
+ pBaroRaw = BARO_AMSYS_OFFSET_MIN;
+ if (pBaroRaw > BARO_AMSYS_OFFSET_MAX)
+ pBaroRaw = BARO_AMSYS_OFFSET_MAX;
- //Convert to pressure
- baro_amsys_p = (float)(pBaroRaw-BARO_AMSYS_OFFSET_MIN)*BARO_AMSYS_MAX_PRESSURE/(float)(BARO_AMSYS_OFFSET_MAX-BARO_AMSYS_OFFSET_MIN);
- if (!baro_amsys_offset_init) {
- --baro_amsys_cnt;
- // Check if averaging completed
- if (baro_amsys_cnt == 0) {
- // Calculate average
- baro_amsys_offset = (float)(baro_amsys_offset_tmp / BARO_AMSYS_OFFSET_NBSAMPLES_AVRG);
- ref_alt_init = GROUND_ALT;
- baro_amsys_offset_init = TRUE;
+ //Convert to pressure
+ baro_amsys_p = (float)(pBaroRaw-BARO_AMSYS_OFFSET_MIN)*BARO_AMSYS_MAX_PRESSURE/(float)(BARO_AMSYS_OFFSET_MAX-BARO_AMSYS_OFFSET_MIN);
+ if (!baro_amsys_offset_init) {
+ --baro_amsys_cnt;
+ // Check if averaging completed
+ if (baro_amsys_cnt == 0) {
+ // Calculate average
+ baro_amsys_offset = (float)(baro_amsys_offset_tmp / BARO_AMSYS_OFFSET_NBSAMPLES_AVRG);
+ ref_alt_init = GROUND_ALT;
+ baro_amsys_offset_init = TRUE;
- // hight over Sea level at init point
- //baro_amsys_offset_altitude = 288.15 / 0.0065 * (1 - pow((baro_amsys_p)/1013.25 , 1/5.255));
- }
- // Check if averaging needs to continue
- else if (baro_amsys_cnt <= BARO_AMSYS_OFFSET_NBSAMPLES_AVRG)
- baro_amsys_offset_tmp += baro_amsys_p;
+ // hight over Sea level at init point
+ //baro_amsys_offset_altitude = 288.15 / 0.0065 * (1 - pow((baro_amsys_p)/1013.25 , 1/5.255));
+ }
+ // Check if averaging needs to continue
+ else if (baro_amsys_cnt <= BARO_AMSYS_OFFSET_NBSAMPLES_AVRG)
+ baro_amsys_offset_tmp += baro_amsys_p;
- baro_amsys_altitude = 0.0;
+ baro_amsys_altitude = 0.0;
- }
- else {
- // Lowpassfiltering and convert pressure to altitude
- baro_amsys_altitude = baro_filter * baro_old + (1 - baro_filter) * (baro_amsys_offset-baro_amsys_p)/(1.2041*9.81);
- baro_old = baro_amsys_altitude;
- //New value available
- }
- baro_amsys_abs_altitude=baro_amsys_altitude+ref_alt_init;
- } /*else {
- baro_amsys_abs_altitude = 0.0;
- }*/
+ }
+ else {
+ // Lowpassfiltering and convert pressure to altitude
+ baro_amsys_altitude = baro_filter * baro_old + (1 - baro_filter) * (baro_amsys_offset-baro_amsys_p)*baro_scale/(1.2041*9.81);
+ baro_old = baro_amsys_altitude;
+ //New value available
+ }
+ baro_amsys_abs_altitude=baro_amsys_altitude+ref_alt_init;
+ } /*else {
+ baro_amsys_abs_altitude = 0.0;
+ }*/
- // Transaction has been read
- baro_amsys_i2c_trans.status = I2CTransDone;
-#ifdef SENSOR_SYNC_SEND
- DOWNLINK_SEND_AMSYS_BARO(DefaultChannel, DefaultDevice, &pBaroRaw, &baro_amsys_p, &baro_amsys_offset, &ref_alt_init, &baro_amsys_abs_altitude, &baro_amsys_altitude, &baro_amsys_temp)
-#else
- RunOnceEvery(10, DOWNLINK_SEND_AMSYS_BARO(DefaultChannel, DefaultDevice, &pBaroRaw, &baro_amsys_p, &baro_amsys_offset, &ref_alt_init, &baro_amsys_abs_altitude, &baro_amsys_altitude, &baro_amsys_temp));
-#endif
-
+ // Transaction has been read
+ baro_amsys_i2c_trans.status = I2CTransDone;
}
diff --git a/sw/airborne/modules/sensors/baro_amsys.h b/sw/airborne/modules/sensors/baro_amsys.h
index 98f028582f..94429a402e 100644
--- a/sw/airborne/modules/sensors/baro_amsys.h
+++ b/sw/airborne/modules/sensors/baro_amsys.h
@@ -33,10 +33,10 @@
extern uint16_t baro_amsys_adc;
// extern float baro_amsys_offset;
extern bool_t baro_amsys_valid;
-// extern bool_t baro_amsys_enabled;
+extern bool_t baro_amsys_enabled;
extern float baro_amsys_altitude;
-// extern float baro_amsys_r;
-// extern float baro_amsys_sigma2;
+extern float baro_amsys_r;
+extern float baro_amsys_sigma2;
extern float baro_filter;
extern struct i2c_transaction baro_amsys_i2c_trans;
diff --git a/sw/airborne/modules/sensors/baro_ets.c b/sw/airborne/modules/sensors/baro_ets.c
index c3b89644d0..c4301495e5 100644
--- a/sw/airborne/modules/sensors/baro_ets.c
+++ b/sw/airborne/modules/sensors/baro_ets.c
@@ -43,6 +43,7 @@
#include "mcu_periph/i2c.h"
#include "state.h"
#include
+#include "mcu_periph/sys_time.h"
#include "subsystems/nav.h"
@@ -50,12 +51,12 @@
#include "subsystems/gps.h"
#endif
-#ifdef BARO_ETS_TELEMETRY
+#ifdef BARO_ETS_SYNC_SEND
#include "mcu_periph/uart.h"
#include "messages.h"
#include "subsystems/datalink/downlink.h"
-#endif //BARO_ETS_TELEMETRY
+#endif //BARO_ETS_SYNC_SEND
#define BARO_ETS_ADDR 0xE8
#define BARO_ETS_REG 0x07
@@ -72,6 +73,13 @@
#ifndef BARO_ETS_I2C_DEV
#define BARO_ETS_I2C_DEV i2c0
#endif
+PRINT_CONFIG_VAR(BARO_ETS_I2C_DEV)
+
+/** delay in seconds until sensor is read after startup */
+#ifndef BARO_ETS_START_DELAY
+#define BARO_ETS_START_DELAY 0.2
+#endif
+PRINT_CONFIG_VAR(BARO_ETS_START_DELAY)
// Global variables
uint16_t baro_ets_adc;
@@ -85,16 +93,18 @@ float baro_ets_sigma2;
struct i2c_transaction baro_ets_i2c_trans;
// Local variables
-bool_t baro_ets_offset_init;
+bool_t baro_ets_offset_init;
uint32_t baro_ets_offset_tmp;
uint16_t baro_ets_cnt;
+uint32_t baro_ets_delay_time;
+bool_t baro_ets_delay_done;
void baro_ets_init( void ) {
baro_ets_adc = 0;
baro_ets_altitude = 0.0;
baro_ets_offset = 0;
baro_ets_offset_tmp = 0;
- baro_ets_valid = TRUE;
+ baro_ets_valid = FALSE;
baro_ets_offset_init = FALSE;
baro_ets_enabled = TRUE;
baro_ets_cnt = BARO_ETS_OFFSET_NBSAMPLES_INIT + BARO_ETS_OFFSET_NBSAMPLES_AVRG;
@@ -102,15 +112,22 @@ void baro_ets_init( void ) {
baro_ets_sigma2 = BARO_ETS_SIGMA2;
baro_ets_i2c_trans.status = I2CTransDone;
+
+ baro_ets_delay_done = FALSE;
+ SysTimeTimerStart(baro_ets_delay_time);
}
void baro_ets_read_periodic( void ) {
// Initiate next read
#ifndef SITL
+ if (!baro_ets_delay_done) {
+ if (SysTimeTimer(baro_ets_delay_time) < USEC_OF_SEC(BARO_ETS_START_DELAY)) return;
+ else baro_ets_delay_done = TRUE;
+ }
if (baro_ets_i2c_trans.status == I2CTransDone)
i2c_receive(&BARO_ETS_I2C_DEV, &baro_ets_i2c_trans, BARO_ETS_ADDR, 2);
#else // SITL
- /* fake an offset so sim works for under hmsl as well */
+ /* fake an offset so sim works as well */
if (!baro_ets_offset_init) {
baro_ets_offset = 12400;
baro_ets_offset_init = TRUE;
@@ -120,7 +137,7 @@ void baro_ets_read_periodic( void ) {
baro_ets_valid = TRUE;
#endif
-#ifdef BARO_ETS_TELEMETRY
+#ifdef BARO_ETS_SYNC_SEND
DOWNLINK_SEND_BARO_ETS(DefaultChannel, DefaultDevice, &baro_ets_adc, &baro_ets_offset, &baro_ets_altitude);
#endif
}
@@ -158,7 +175,7 @@ void baro_ets_read_event( void ) {
if (baro_ets_offset_init) {
baro_ets_altitude = ground_alt + BARO_ETS_SCALE * (float)(baro_ets_offset-baro_ets_adc);
// New value available
-#ifdef BARO_ETS_TELEMETRY
+#ifdef BARO_ETS_SYNC_SEND
DOWNLINK_SEND_BARO_ETS(DefaultChannel, DefaultDevice, &baro_ets_adc, &baro_ets_offset, &baro_ets_altitude);
#endif
} else {
diff --git a/sw/airborne/modules/sensors/baro_ms5611_i2c.c b/sw/airborne/modules/sensors/baro_ms5611_i2c.c
index dbe127b4f8..91d2deecbc 100644
--- a/sw/airborne/modules/sensors/baro_ms5611_i2c.c
+++ b/sw/airborne/modules/sensors/baro_ms5611_i2c.c
@@ -52,6 +52,7 @@ uint8_t ms5611_status;
uint16_t ms5611_c[PROM_NB];
uint32_t ms5611_d1, ms5611_d2;
int32_t prom_cnt;
+int64_t baroms;
float fbaroms, ftempms;
float baro_ms5611_alt;
bool_t baro_ms5611_enabled;
@@ -190,7 +191,7 @@ void baro_ms5611_event( void ) {
break;
case MS5611_ADC_D2: {
- int64_t dt, baroms, tempms, off, sens, t2, off2, sens2;
+ int64_t dt, tempms, off, sens, t2, off2, sens2;
/* read D2 (temperature) */
ms5611_d2 = (ms5611_trans.buf[0] << 16) |
(ms5611_trans.buf[1] << 8) |
diff --git a/sw/airborne/modules/sensors/baro_ms5611_i2c.h b/sw/airborne/modules/sensors/baro_ms5611_i2c.h
index aeef952cd6..cad37d60db 100644
--- a/sw/airborne/modules/sensors/baro_ms5611_i2c.h
+++ b/sw/airborne/modules/sensors/baro_ms5611_i2c.h
@@ -20,6 +20,7 @@ extern bool_t baro_ms5611_valid;
extern bool_t baro_ms5611_enabled;
extern float baro_ms5611_r;
extern float baro_ms5611_sigma2;
+extern int64_t baroms;
enum ms5611_stat{
MS5611_UNINIT,
@@ -35,11 +36,11 @@ enum ms5611_stat{
MS5611_ADC_D2
};
-void baro_ms5611_init(void);
-void baro_ms5611_periodic(void);
-void baro_ms5611_d1(void);
-void baro_ms5611_d2(void);
-void baro_ms5611_event(void);
+extern void baro_ms5611_init(void);
+extern void baro_ms5611_periodic(void);
+extern void baro_ms5611_d1(void);
+extern void baro_ms5611_d2(void);
+extern void baro_ms5611_event(void);
#define BaroMs5611Update(_b) { if (baro_ms5611_valid) { _b = baro_ms5611_alt; baro_ms5611_valid = FALSE; } }
diff --git a/sw/airborne/subsystems/actuators/motor_mixing.c b/sw/airborne/subsystems/actuators/motor_mixing.c
index 313ac9df90..e79daa50ed 100644
--- a/sw/airborne/subsystems/actuators/motor_mixing.c
+++ b/sw/airborne/subsystems/actuators/motor_mixing.c
@@ -172,13 +172,17 @@ void motor_mixing_run(bool_t motors_on, bool_t override_on, pprz_t in_cmd[] ) {
if (min_cmd < MOTOR_MIXING_MIN_MOTOR && max_cmd > MOTOR_MIXING_MAX_MOTOR)
motor_mixing.nb_failure++;
- if (min_cmd < MOTOR_MIXING_MIN_MOTOR) {
- int32_t saturation_offset = MOTOR_MIXING_MIN_MOTOR - min_cmd;
+ /* In case of both min and max saturation, only lower the throttle
+ * instead of applying both. This should prevent your quad shooting up,
+ * but it might loose altitude in case of such a saturation failure.
+ */
+ if (max_cmd > MOTOR_MIXING_MAX_MOTOR) {
+ int32_t saturation_offset = MOTOR_MIXING_MAX_MOTOR - max_cmd;
BoundAbs(saturation_offset, MOTOR_MIXING_MAX_SATURATION_OFFSET);
offset_commands(saturation_offset);
}
- if (max_cmd > MOTOR_MIXING_MAX_MOTOR) {
- int32_t saturation_offset = MOTOR_MIXING_MAX_MOTOR - max_cmd;
+ else if (min_cmd < MOTOR_MIXING_MIN_MOTOR) {
+ int32_t saturation_offset = MOTOR_MIXING_MIN_MOTOR - min_cmd;
BoundAbs(saturation_offset, MOTOR_MIXING_MAX_SATURATION_OFFSET);
offset_commands(saturation_offset);
}
diff --git a/sw/airborne/subsystems/gps/gps_ardrone2.c b/sw/airborne/subsystems/gps/gps_ardrone2.c
index 60a1e5db78..0326f0dd64 100644
--- a/sw/airborne/subsystems/gps/gps_ardrone2.c
+++ b/sw/airborne/subsystems/gps/gps_ardrone2.c
@@ -36,6 +36,7 @@ void gps_impl_init( void ) {
}
void gps_ardrone2_parse(navdata_gps_t *navdata_gps) {
+ int i;
// Set the lla double struct from the navdata
struct LlaCoor_d gps_lla_d;
gps_lla_d.lat = RadOfDeg(navdata_gps->lat);
@@ -51,6 +52,12 @@ void gps_ardrone2_parse(navdata_gps_t *navdata_gps) {
LLA_BFP_OF_REAL(gps.lla_pos, gps_lla_d);
// TODO: parse other stuff
+ gps.nb_channels = GPS_NB_CHANNELS;
+
+ for(i = 0; i < GPS_NB_CHANNELS; i++) {
+ gps.svinfos[i].svid = navdata_gps->channels[i].sat;
+ gps.svinfos[i].cno = navdata_gps->channels[i].cn0;
+ }
// Check if we have a fix TODO: check if 2D or 3D fix?
if (navdata_gps->gps_state == 1)
diff --git a/sw/airborne/subsystems/gps/gps_ardrone2.h b/sw/airborne/subsystems/gps/gps_ardrone2.h
index 42e926ff34..2995d0f853 100644
--- a/sw/airborne/subsystems/gps/gps_ardrone2.h
+++ b/sw/airborne/subsystems/gps/gps_ardrone2.h
@@ -30,7 +30,7 @@
#include "boards/ardrone/at_com.h"
-//#define GPS_NB_CHANNELS 12 // TODO: Get channels out of packet
+#define GPS_NB_CHANNELS 12
extern bool_t gps_ardrone2_available;
/*
diff --git a/sw/airborne/subsystems/imu/imu_aspirin2.c b/sw/airborne/subsystems/imu/imu_aspirin2.c
deleted file mode 100644
index b467e1bd35..0000000000
--- a/sw/airborne/subsystems/imu/imu_aspirin2.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2012 Christophe DeWagter
- *
- * 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.
- */
-#include "subsystems/imu.h"
-
-#include "led.h"
-#include "mcu_periph/spi.h"
-
-// Peripherials
-#include "peripherals/mpu60x0_regs.h"
-#include "peripherals/hmc58xx_regs.h"
-#include "peripherals/ms5611.h"
-
-#ifndef MPU6000_SLAVE_IDX
-#define MPU6000_SLAVE_IDX SPI_SLAVE2
-#endif
-
-#ifndef MPU6000_SPI_DEV
-#define MPU6000_SPI_DEV spi2
-#endif
-
-/* HMC58XX default conf */
-#ifndef HMC58XX_DO
-#define HMC58XX_DO 0x6 // Data Output Rate (6 -> 50Hz with HMC5843, 75Hz with HMC5883)
-#endif
-#ifndef HMC58XX_MS
-#define HMC58XX_MS 0x0 // Measurement configuration
-#endif
-#ifndef HMC58XX_GN
-#define HMC58XX_GN 0x1 // Gain configuration (1 -> +- 1 Gauss)
-#endif
-#ifndef HMC58XX_MD
-#define HMC58XX_MD 0x0 // Continious measurement mode
-#endif
-
-#define HMC58XX_CRA ((HMC58XX_DO<<2)|(HMC58XX_MS))
-#define HMC58XX_CRB (HMC58XX_GN<<5)
-
-struct ImuAspirin2 imu_aspirin2;
-
-struct spi_transaction aspirin2_mpu60x0;
-
-// initialize peripherals
-static void mpu_configure(void);
-static void trans_cb( struct spi_transaction *trans );
-
-void imu_impl_init(void) {
- aspirin2_mpu60x0.select = SPISelectUnselect;
- aspirin2_mpu60x0.cpol = SPICpolIdleHigh;
- aspirin2_mpu60x0.cpha = SPICphaEdge2;
- aspirin2_mpu60x0.dss = SPIDss8bit;
- aspirin2_mpu60x0.bitorder = SPIMSBFirst;
- aspirin2_mpu60x0.cdiv = SPIDiv64;
- aspirin2_mpu60x0.slave_idx = MPU6000_SLAVE_IDX;
- aspirin2_mpu60x0.output_length = IMU_ASPIRIN_BUFFER_LEN;
- aspirin2_mpu60x0.input_length = IMU_ASPIRIN_BUFFER_LEN;
- aspirin2_mpu60x0.after_cb = trans_cb;
-
- imu_aspirin2.status = Aspirin2StatusUninit;
- imu_aspirin2.imu_available = FALSE;
- aspirin2_mpu60x0.input_buf = &imu_aspirin2.input_buf_p[0];
- aspirin2_mpu60x0.output_buf = &imu_aspirin2.output_buf_p[0];
-}
-
-
-void imu_periodic(void)
-{
-
- if (imu_aspirin2.status == Aspirin2StatusUninit) {
- mpu_configure();
- imu_aspirin2.status = Aspirin2StatusIdle;
-
- aspirin2_mpu60x0.output_length = 22;
- aspirin2_mpu60x0.input_length = 22;
- aspirin2_mpu60x0.output_buf[0] = MPU60X0_REG_INT_STATUS + MPU60X0_SPI_READ;
- for (int i=1; i6)
- (MPU_DIG_FILTER << 0) ); // Low-Pass Filter
-
- // MPU60X0_REG_SMPLRT_DIV
- mpu_set( MPU60X0_REG_SMPLRT_DIV, MPU_SMPLRT_DIV);
-
- // MPU60X0_REG_GYRO_CONFIG
- mpu_set( MPU60X0_REG_GYRO_CONFIG,
- (3 << 3) ); // -2000deg/sec
-
- // MPU60X0_REG_ACCEL_CONFIG
- mpu_set( MPU60X0_REG_ACCEL_CONFIG,
- (0 << 0) | // No HPFL
- (3 << 3) ); // Full Scale = 16g
-
-#ifndef MPU6000_NO_SLAVES
-PRINT_CONFIG_MSG("Reading MPU slaves")
-
- /////////////////////////////////////
- // SPI Slave Configuration Section
-
- // Power the Aux I2C Circuit:
- // MPU60X0_REG_AUX_VDDIO = 0 (good on startup): (0 << 7); // MPU6000: 0=Vdd. MPU6050 : 0=VLogic 1=Vdd
-
- // MPU60X0_REG_USER_CTRL:
- mpu_set( MPU60X0_REG_USER_CTRL,
- (1 << 5) | // I2C_MST_EN: Enable Aux I2C Master Mode
- (1 << 4) | // I2C_IF_DIS: Disable I2C on primary interface
- (0 << 1) ); // Trigger a I2C_MST_RESET
-
- // Enable the aux i2c
- mpu_set( MPU60X0_REG_I2C_MST_CTRL,
- (0 << 7) | // no multimaster
- (0 << 6) | // do not delay IRQ waiting for all external slaves
- (0 << 5) | // no slave 3 FIFO
- (0 << 4) | // restart or stop/start from one slave to another: read -> write is always stop/start
- (8 << 0) ); // 0=348kHz 8=256kHz, 9=500kHz
-
- mpu_set( MPU60X0_REG_I2C_MST_DELAY,
- (0 << 2) | // No Delay Slave 2
- (1 << 3) ); // Delay Slave 3
-
-#if defined IMU_ASPIRIN_VERSION_2_1 && USE_IMU_ASPIRIN2_BARO_SLAVE
-
- // MS5611 Send Reset
- mpu_set( MPU60X0_REG_I2C_SLV4_ADDR, (MS5611_ADDR0));
- mpu_set( MPU60X0_REG_I2C_SLV4_DO, MS5611_REG_RESET);
- mpu_set( MPU60X0_REG_I2C_SLV4_CTRL,
- (1 << 7) | // Slave 4 enable
- (0 << 6) | // Byte Swap
- (1 << 5) | // Reg_Dis: do not write the register, just the data
- (0 << 0) ); // Full Speed
-
- mpu_wait_slave4_ready();
-
- // Wait at least 2.8ms
-
-#endif // read MS5611 as MPU slave
-
- // HMC5883 Magnetometer Configuration
-
- mpu_set( MPU60X0_REG_I2C_SLV4_ADDR, (HMC58XX_ADDR >> 1));
- mpu_set( MPU60X0_REG_I2C_SLV4_REG, HMC58XX_REG_CFGA);
- mpu_set( MPU60X0_REG_I2C_SLV4_DO, HMC58XX_CRA);
- mpu_set( MPU60X0_REG_I2C_SLV4_CTRL,
- (1 << 7) | // Slave 4 enable
- (0 << 6) | // Byte Swap
- (0 << 0) ); // Full Speed
-
- mpu_wait_slave4_ready();
-
- mpu_set( MPU60X0_REG_I2C_SLV4_ADDR, (HMC58XX_ADDR >> 1));
- mpu_set( MPU60X0_REG_I2C_SLV4_REG, HMC58XX_REG_CFGB);
- mpu_set( MPU60X0_REG_I2C_SLV4_DO, HMC58XX_CRB);
- mpu_set( MPU60X0_REG_I2C_SLV4_CTRL,
- (1 << 7) | // Slave 4 enable
- (0 << 6) | // Byte Swap
- (0 << 0) ); // Full Speed
-
- mpu_wait_slave4_ready();
-
- mpu_set( MPU60X0_REG_I2C_SLV4_ADDR, (HMC58XX_ADDR >> 1));
- mpu_set( MPU60X0_REG_I2C_SLV4_REG, HMC58XX_REG_MODE);
- mpu_set( MPU60X0_REG_I2C_SLV4_DO, HMC58XX_MD);
- mpu_set( MPU60X0_REG_I2C_SLV4_CTRL,
- (1 << 7) | // Slave 4 enable
- (0 << 6) | // Byte Swap
- (3 << 0) ); // From now on a delayed rate of 1/4 is defined...
-
- // HMC5883 Reading:
- // a) write hmc-register to HMC
- // b) read 6 bytes from HMC
-
- mpu_set( MPU60X0_REG_I2C_SLV0_ADDR, (HMC58XX_ADDR >> 1) | MPU60X0_SPI_READ);
- mpu_set( MPU60X0_REG_I2C_SLV0_REG, HMC58XX_REG_DATXM);
- // Put the enable command as last.
- mpu_set( MPU60X0_REG_I2C_SLV0_CTRL,
- (1 << 7) | // Slave 0 enable
- (0 << 6) | // Byte Swap
- (6 << 0) ); // Read 6 bytes
-
- // Slave 0 Control:
-
-#if defined IMU_ASPIRIN_VERSION_2_1 && USE_IMU_ASPIRIN2_BARO_SLAVE
-PRINT_CONFIG_MSG("Reading the MS5611 as MPU slave")
-/*
-
-
- // Read MS5611 Calibration
- mpu_set( MPU60X0_REG_I2C_SLV1_ADDR, (MS5611_ADDR0) | MPU60X0_SPI_READ);
- mpu_set( MPU60X0_REG_I2C_SLV1_REG, MS5611_REG_ADCREAD);
- // Put the enable command as last.
- mpu_set( MPU60X0_REG_I2C_SLV1_CTRL,
- (1 << 7) | // Slave 1 enable
- (0 << 6) | // Byte Swap
- (3 << 0) ); // Read 6 bytes
-
-*/
-
- // Full Rate Request For Pressure
- mpu_set( MPU60X0_REG_I2C_SLV2_ADDR, (MS5611_ADDR0));
- mpu_set( MPU60X0_REG_I2C_SLV2_DO, 0x48);
- // Put the enable command as last.
- mpu_set( MPU60X0_REG_I2C_SLV2_CTRL,
- (1 << 7) | // Slave 2 enable
- (0 << 6) | // Byte Swap
- (1 << 5) | // Rig Dis: Write Only
- (1 << 0) ); // Write 1 byte
-
- // Reduced rate request For Temperature: Overwrites the Pressure Request
- mpu_set( MPU60X0_REG_I2C_SLV3_ADDR, (MS5611_ADDR0));
- mpu_set( MPU60X0_REG_I2C_SLV3_DO, 0x58);
- // Put the enable command as last.
- mpu_set( MPU60X0_REG_I2C_SLV3_CTRL,
- (1 << 7) | // Slave 2 enable
- (0 << 6) | // Byte Swap
- (1 << 5) | // Rig Dis: Write Only
- (1 << 0) ); // Write 1 byte
-
- mpu_set( MPU60X0_REG_I2C_SLV1_ADDR, (MS5611_ADDR0) | MPU60X0_SPI_READ);
- mpu_set( MPU60X0_REG_I2C_SLV1_REG, MS5611_REG_ADCREAD);
- // Put the enable command as last.
- mpu_set( MPU60X0_REG_I2C_SLV1_CTRL,
- (1 << 7) | // Slave 1 enable
- (0 << 6) | // Byte Swap
- (3 << 0) ); // Read 6 bytes
-
-#endif // read MS5611 as MPU slave
-
-#endif
-
-}
-
diff --git a/sw/airborne/subsystems/imu/imu_aspirin2.h b/sw/airborne/subsystems/imu/imu_aspirin2.h
deleted file mode 100644
index b55872f453..0000000000
--- a/sw/airborne/subsystems/imu/imu_aspirin2.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2012 Christophe DeWagter
- *
- * 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.
- */
-
-#ifndef IMU_ASPIRIN_2_H
-#define IMU_ASPIRIN_2_H
-
-#include "generated/airframe.h"
-#include "subsystems/imu.h"
-
-
-#if defined IMU_ASPIRIN_VERSION_2_1 || defined IMU_ASPIRIN_VERSION_2_2
-#if !defined IMU_MAG_X_SIGN & !defined IMU_MAG_Y_SIGN & !defined IMU_MAG_Z_SIGN
-#define IMU_MAG_X_SIGN 1
-#define IMU_MAG_Y_SIGN 1
-#define IMU_MAG_Z_SIGN 1
-#endif
-#endif
-
-#if !defined IMU_GYRO_P_SIGN & !defined IMU_GYRO_Q_SIGN & !defined IMU_GYRO_R_SIGN
-#define IMU_GYRO_P_SIGN 1
-#define IMU_GYRO_Q_SIGN 1
-#define IMU_GYRO_R_SIGN 1
-#endif
-#if !defined IMU_ACCEL_X_SIGN & !defined IMU_ACCEL_Y_SIGN & !defined IMU_ACCEL_Z_SIGN
-#define IMU_ACCEL_X_SIGN 1
-#define IMU_ACCEL_Y_SIGN 1
-#define IMU_ACCEL_Z_SIGN 1
-#endif
-
-/** default gyro sensitivy and neutral from the datasheet
- * MPU60X0 has 16.4 LSB/(deg/s) at 2000deg/s range
- * sens = 1/16.4 * pi/180 * 2^INT32_RATE_FRAC
- * sens = 1/16.4 * pi/180 * 4096 = 4.359066229
- */
-#if !defined IMU_GYRO_P_SENS & !defined IMU_GYRO_Q_SENS & !defined IMU_GYRO_R_SENS
-#define IMU_GYRO_P_SENS 4.359
-#define IMU_GYRO_P_SENS_NUM 4359
-#define IMU_GYRO_P_SENS_DEN 1000
-#define IMU_GYRO_Q_SENS 4.359
-#define IMU_GYRO_Q_SENS_NUM 4359
-#define IMU_GYRO_Q_SENS_DEN 1000
-#define IMU_GYRO_R_SENS 4.359
-#define IMU_GYRO_R_SENS_NUM 4359
-#define IMU_GYRO_R_SENS_DEN 1000
-#endif
-#if !defined IMU_GYRO_P_NEUTRAL & !defined IMU_GYRO_Q_NEUTRAL & !defined IMU_GYRO_R_NEUTRAL
-#define IMU_GYRO_P_NEUTRAL 0
-#define IMU_GYRO_Q_NEUTRAL 0
-#define IMU_GYRO_R_NEUTRAL 0
-#endif
-
-/** default accel sensitivy from the datasheet
- * MPU60X0 has 2048 LSB/g
- * fixed point sens: 9.81 [m/s^2] / 2048 [LSB/g] * 2^INT32_ACCEL_FRAC
- * sens = 9.81 / 2048 * 1024 = 4.905
- */
-#if !defined IMU_ACCEL_X_SENS & !defined IMU_ACCEL_Y_SENS & !defined IMU_ACCEL_Z_SENS
-#define IMU_ACCEL_X_SENS 4.905
-#define IMU_ACCEL_X_SENS_NUM 4905
-#define IMU_ACCEL_X_SENS_DEN 1000
-#define IMU_ACCEL_Y_SENS 4.905
-#define IMU_ACCEL_Y_SENS_NUM 4905
-#define IMU_ACCEL_Y_SENS_DEN 1000
-#define IMU_ACCEL_Z_SENS 4.905
-#define IMU_ACCEL_Z_SENS_NUM 4905
-#define IMU_ACCEL_Z_SENS_DEN 1000
-#endif
-#if !defined IMU_ACCEL_X_NEUTRAL & !defined IMU_ACCEL_Y_NEUTRAL & !defined IMU_ACCEL_Z_NEUTRAL
-#define IMU_ACCEL_X_NEUTRAL 0
-#define IMU_ACCEL_Y_NEUTRAL 0
-#define IMU_ACCEL_Z_NEUTRAL 0
-#endif
-
-
-enum Aspirin2Status
- { Aspirin2StatusUninit,
- Aspirin2StatusIdle,
- Aspirin2StatusReading
- };
-
-#define IMU_ASPIRIN_BUFFER_LEN 32
-
-struct ImuAspirin2 {
- volatile enum Aspirin2Status status;
- volatile uint8_t imu_available;
- volatile uint8_t input_buf_p[IMU_ASPIRIN_BUFFER_LEN];
- volatile uint8_t output_buf_p[IMU_ASPIRIN_BUFFER_LEN];
-};
-
-extern struct ImuAspirin2 imu_aspirin2;
-
-
-static inline int imu_from_buff(volatile uint8_t *buf)
-{
- int32_t x, y, z, p, q, r, Mx, My, Mz;
-
-#define MPU_OFFSET_STATUS 1
- if (!(buf[MPU_OFFSET_STATUS] & 0x01)) {
- return 0;
- }
-
-#define MPU_OFFSET_GYRO 10
- p = (int16_t) ((buf[0+MPU_OFFSET_GYRO] << 8) | buf[1+MPU_OFFSET_GYRO]);
- q = (int16_t) ((buf[2+MPU_OFFSET_GYRO] << 8) | buf[3+MPU_OFFSET_GYRO]);
- r = (int16_t) ((buf[4+MPU_OFFSET_GYRO] << 8) | buf[5+MPU_OFFSET_GYRO]);
-
-#define MPU_OFFSET_ACC 2
- x = (int16_t) ((buf[0+MPU_OFFSET_ACC] << 8) | buf[1+MPU_OFFSET_ACC]);
- y = (int16_t) ((buf[2+MPU_OFFSET_ACC] << 8) | buf[3+MPU_OFFSET_ACC]);
- z = (int16_t) ((buf[4+MPU_OFFSET_ACC] << 8) | buf[5+MPU_OFFSET_ACC]);
-
-#define MPU_OFFSET_MAG 16
- Mx = (int16_t) ((buf[0+MPU_OFFSET_MAG] << 8) | buf[1+MPU_OFFSET_MAG]);
- My = (int16_t) ((buf[2+MPU_OFFSET_MAG] << 8) | buf[3+MPU_OFFSET_MAG]);
- Mz = (int16_t) ((buf[4+MPU_OFFSET_MAG] << 8) | buf[5+MPU_OFFSET_MAG]);
-
-#ifdef LISA_M_LONGITUDINAL_X
- RATES_ASSIGN(imu.gyro_unscaled, q, -p, r);
- VECT3_ASSIGN(imu.accel_unscaled, y, -x, z);
- VECT3_ASSIGN(imu.mag_unscaled, -Mx, -Mz, My);
-#else
- RATES_ASSIGN(imu.gyro_unscaled, p, q, r);
- VECT3_ASSIGN(imu.accel_unscaled, x, y, z);
- VECT3_ASSIGN(imu.mag_unscaled, Mz, -Mx, My);
-#endif
-
- return 1;
-}
-
-
-static inline void imu_aspirin2_event(void (* _gyro_handler)(void), void (* _accel_handler)(void), void (* _mag_handler)(void))
-{
- if (imu_aspirin2.status == Aspirin2StatusUninit) return;
-
- if (imu_aspirin2.imu_available) {
- imu_aspirin2.imu_available = FALSE;
- if (imu_from_buff(imu_aspirin2.input_buf_p)) {
- _gyro_handler();
- _accel_handler();
- _mag_handler();
- }
- }
-}
-
-#define ImuEvent(_gyro_handler, _accel_handler, _mag_handler) { \
- imu_aspirin2_event(_gyro_handler, _accel_handler, _mag_handler); \
-}
-
-#endif /* IMU_ASPIRIN_2_H */
diff --git a/sw/airborne/subsystems/imu/imu_aspirin_2_spi.c b/sw/airborne/subsystems/imu/imu_aspirin_2_spi.c
index 84918649e4..bd463158df 100644
--- a/sw/airborne/subsystems/imu/imu_aspirin_2_spi.c
+++ b/sw/airborne/subsystems/imu/imu_aspirin_2_spi.c
@@ -145,10 +145,11 @@ void imu_aspirin2_event(void)
{
mpu60x0_spi_event(&imu_aspirin2.mpu);
if (imu_aspirin2.mpu.data_available) {
+ /* HMC5883 has xzy order of axes in returned data */
struct Int32Vect3 mag;
mag.x = Int16FromBuf(imu_aspirin2.mpu.data_ext, 0);
- mag.y = Int16FromBuf(imu_aspirin2.mpu.data_ext, 2);
- mag.z = Int16FromBuf(imu_aspirin2.mpu.data_ext, 4);
+ mag.z = Int16FromBuf(imu_aspirin2.mpu.data_ext, 2);
+ mag.y = Int16FromBuf(imu_aspirin2.mpu.data_ext, 4);
#ifdef LISA_M_LONGITUDINAL_X
RATES_ASSIGN(imu.gyro_unscaled,
imu_aspirin2.mpu.data_rates.rates.q,
@@ -158,11 +159,11 @@ void imu_aspirin2_event(void)
imu_aspirin2.mpu.data_accel.vect.y,
-imu_aspirin2.mpu.data_accel.vect.x,
imu_aspirin2.mpu.data_accel.vect.z);
- VECT3_ASSIGN(imu.mag_unscaled, -mag.x, -mag.z, mag.y);
+ VECT3_ASSIGN(imu.mag_unscaled, -mag.x, -mag.y, mag.z);
#else
RATES_COPY(imu.gyro_unscaled, imu_aspirin2.mpu.data_rates.rates);
VECT3_COPY(imu.accel_unscaled, imu_aspirin2.mpu.data_accel.vect);
- VECT3_ASSIGN(imu.mag_unscaled, mag.z, -mag.x, mag.y)
+ VECT3_ASSIGN(imu.mag_unscaled, mag.y, -mag.x, mag.z)
#endif
imu_aspirin2.mpu.data_available = FALSE;
imu_aspirin2.gyro_valid = TRUE;
diff --git a/sw/airborne/subsystems/ins/ins_alt_float.c b/sw/airborne/subsystems/ins/ins_alt_float.c
index ea49a6d3e1..b2c78c6f2c 100644
--- a/sw/airborne/subsystems/ins/ins_alt_float.c
+++ b/sw/airborne/subsystems/ins/ins_alt_float.c
@@ -192,6 +192,12 @@ void alt_kalman(float z_meas) {
R = baro_ms5611_r;
SIGMA2 = baro_ms5611_sigma2;
} else
+#elif USE_BARO_AMSYS
+ if (baro_amsys_enabled) {
+ DT = BARO_AMSYS_DT;
+ R = baro_amsys_r;
+ SIGMA2 = baro_amsys_sigma2;
+ } else
#elif USE_BARO_BMP
if (baro_bmp_enabled) {
DT = BARO_BMP_DT;
diff --git a/sw/airborne/subsystems/ins/ins_alt_float.h b/sw/airborne/subsystems/ins/ins_alt_float.h
index a3bf0ef210..2797e679c7 100644
--- a/sw/airborne/subsystems/ins/ins_alt_float.h
+++ b/sw/airborne/subsystems/ins/ins_alt_float.h
@@ -52,6 +52,10 @@
#include "modules/sensors/baro_ms5611_i2c.h"
#endif
+#if USE_BARO_AMSYS
+#include "modules/sensors/baro_amsys.h"
+#endif
+
extern int32_t ins_qfe;
extern float ins_baro_alt;
extern bool_t ins_baro_initialised;
diff --git a/sw/extras/chdk/pictuav.lua b/sw/extras/chdk/pictuav.lua
new file mode 100644
index 0000000000..07c56de78f
--- /dev/null
+++ b/sw/extras/chdk/pictuav.lua
@@ -0,0 +1,168 @@
+--[[
+@title PictUAV
+@param d Display off frame 0=never
+@default d 0
+--]]
+
+-- Developed on IXUS 230 HS. Other cameras should work as well, but some errors or crashes are possible
+-- also considering that some firmwares still have CHDK bugs.
+--
+-- Other settings in the camera that you should try to manipulate to reduce the time between taking pictures:
+-- CHDK menu
+-- Extra Photo overrides
+-- Disable overrides : Off
+-- Do not override shutter speed ( I allow the camera to determine exposure time, but feel free to experiment)
+-- ND filter state: Out (removes ND filter to allow more light to fall on the sensor )
+-- Override subj. dist. value: 65535. (good to keep it there)
+-- Do not save RAW images, they take longer
+--
+-- Camera menu
+-- Use P mode, certainly not automatic
+-- If you can hardset the focus, do this towards infinity
+-- Play around with aperture. Smaller apertures are better for more sharpness, but not every camera allows you to.
+-- (Some cameras have really bad behaviour on larger apertures that allow more light through, especially at edges).
+-- Disable IS (plane vibrations mess up its function and increases the chance of blur)
+-- Take Large images with Fine resolution.
+-- Turn "Review" mode off.
+-- Consider hard-setting ISO, but consider local weather. If set too high, shutter time goes up, which causes blur.
+-- Blur can then also occur in areas where there is little light reflection from the earth.
+--
+-- How to use the script:
+-- Load this on the card under "CHDK/SCRIPTS"
+-- Enter the CHDK menu through your "ALT" button
+-- Under scripts, select the script and specify "Autostart: on"
+--
+-- As the camera starts up, this also loads. with the shutter button pressed, you can interrupt the script
+-- Then press the "ALT" button to disable the scripting actuator.
+-- Press the shutter button to extend the lens
+-- Press "ALT" again to bring up the scripting actuator.
+-- Press the shutter button to reinitiate the script.
+-- If you have a IXUS 230HS like me, the focus can't be set automatically. Point the camera at a distant object while the script
+-- is starting. It should say "Focused", after which it's ready for use.
+--
+-- Example paparazzi airframe configuration:
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+
+print( "PictUAV Started " )
+
+function print_status (frame)
+ local free = get_jpg_count()
+ print("#" .. frame )
+end
+
+-- switch to autofocus mode, pre-focus, then go to manual focus mode (locking focus there).
+-- this helps to reduce the delay between the signal and taking the picture.
+function pre_focus()
+ local focused = false
+ local try = 1
+ while not focused and try <= 5 do
+ print("Pre-focus attempt " .. try)
+ press("shoot_half")
+ sleep(2000)
+ if get_prop(18) > 0 then
+ print("Focused")
+ focused = true
+ set_aflock(1)
+ end
+ release("shoot_half")
+ sleep(500)
+ try = try + 1
+ end
+ return focused
+end
+
+-- set aperture/shooting mode to landscape
+set_prop(6,3)
+
+ap = get_prop(6)
+print ("AF(3=inf,4=MF) "..ap)
+
+-- Turn IS off
+set_prop(145, 3)
+
+-- set P mode
+set_capture_mode(2)
+sleep(1000)
+
+-- Get focusing mode
+p = get_prop(6)
+if (p==3) then
+ print "Inf set."
+else
+ -- on ixus230hs, no explicit MF.
+ -- so set to infinity (3)
+ while (p ~= 3) do
+ press "left"
+ release "left"
+ p = get_prop (6)
+ end
+ print "Focus set to infinity"
+end
+
+-- on ixus230hs set focus doesn't fail, but doesn't do anything.
+set_focus(100)
+print "set_focus 100"
+sleep(2000)
+f = get_focus
+
+-- on ixus230hs set focus doesn't fail, but doesn't do anything.
+set_focus( 65535 )
+print "set_focus 65535"
+sleep( 2000)
+g = get_focus
+
+if (f==g) then
+ print "set_focus inop"
+ -- if focusing until here didn't work, pre-focus using a different method.
+ pre_focus()
+else
+ -- set_aflock(1) fails when the camera isn't knowingly focused.
+ print( "Setting aflock 1" )
+ sleep(1000)
+ set_aflock( 1 )
+end
+
+-- measuring the pulse on CHDK isn't necessarily that accurate, they can easily vary by 40ms.
+-- Since I'm using a 100ms wait here, the variance for a shoot is around 140ms.
+-- If the pulse is 250ms, then I should allow for anything down to 110.
+-- For Paparazzi, taking a single picture using the button may not work because the timing may be very off
+-- considering the 4Hz loop (this requires a change in the cam module for paparazzi).
+
+print( "PictUAV loop " )
+a = -1
+repeat
+ a = get_usb_power(0)
+ -- a pulse is detected longer than ~610ms.
+ if (a>61) then
+ print( "shutting down " )
+ shut_down()
+ sleep(1500)
+ break
+ end
+ -- a pulse longer than ~100ms is detected.
+ if (a>10) then
+
+ frame = 1
+ shoot()
+
+ frame = frame + 1
+
+ end
+ sleep(100)
+until ( false )
+print( "PictUAV ended " )
+