diff --git a/conf/airframes/ENAC/fixed-wing/apogee.xml b/conf/airframes/ENAC/fixed-wing/apogee.xml index d98be030f0..5c62d51f53 100644 --- a/conf/airframes/ENAC/fixed-wing/apogee.xml +++ b/conf/airframes/ENAC/fixed-wing/apogee.xml @@ -23,19 +23,17 @@ - - + + - + - - - + diff --git a/conf/airframes/ENAC/fixed-wing/eternity1.xml b/conf/airframes/ENAC/fixed-wing/eternity1.xml index 6a9595967d..06bd7fc9d1 100644 --- a/conf/airframes/ENAC/fixed-wing/eternity1.xml +++ b/conf/airframes/ENAC/fixed-wing/eternity1.xml @@ -26,9 +26,7 @@ - - - + diff --git a/conf/airframes/ENAC/fixed-wing/firestorm.xml b/conf/airframes/ENAC/fixed-wing/firestorm.xml index 584e3fb3a9..222712c259 100644 --- a/conf/airframes/ENAC/fixed-wing/firestorm.xml +++ b/conf/airframes/ENAC/fixed-wing/firestorm.xml @@ -32,9 +32,7 @@ - - - + diff --git a/conf/airframes/ENAC/fixed-wing/funjet2.xml b/conf/airframes/ENAC/fixed-wing/funjet2.xml index bd474733af..56455152a5 100644 --- a/conf/airframes/ENAC/fixed-wing/funjet2.xml +++ b/conf/airframes/ENAC/fixed-wing/funjet2.xml @@ -39,9 +39,7 @@ - - - + diff --git a/conf/airframes/ENAC/fixed-wing/mythe.xml b/conf/airframes/ENAC/fixed-wing/mythe.xml index 5a39cdc4fa..f6c226b11b 100644 --- a/conf/airframes/ENAC/fixed-wing/mythe.xml +++ b/conf/airframes/ENAC/fixed-wing/mythe.xml @@ -66,9 +66,7 @@ - - - + diff --git a/conf/airframes/ENAC/fixed-wing/weasel.xml b/conf/airframes/ENAC/fixed-wing/weasel.xml index 744c25880c..f15a4b5c41 100644 --- a/conf/airframes/ENAC/fixed-wing/weasel.xml +++ b/conf/airframes/ENAC/fixed-wing/weasel.xml @@ -20,26 +20,27 @@ - + - - - + - + + + + + + - - - - + + @@ -49,17 +50,11 @@ - - - - - - - - + + @@ -83,13 +78,13 @@ - - + +
- - + +
@@ -123,8 +118,8 @@
- - + +
@@ -161,15 +156,15 @@ - - - + + + - - - + + + @@ -206,8 +201,8 @@ - - + + @@ -234,7 +229,7 @@ - + diff --git a/conf/airframes/ENAC/quadrotor/booz2_g1.xml b/conf/airframes/ENAC/quadrotor/booz2_g1.xml index 472c32d189..ae5f73a8eb 100644 --- a/conf/airframes/ENAC/quadrotor/booz2_g1.xml +++ b/conf/airframes/ENAC/quadrotor/booz2_g1.xml @@ -213,7 +213,7 @@ - +
diff --git a/conf/airframes/ENAC/quadrotor/hen1.xml b/conf/airframes/ENAC/quadrotor/hen1.xml index 78b81b8e0b..2c0bdb49ae 100644 --- a/conf/airframes/ENAC/quadrotor/hen1.xml +++ b/conf/airframes/ENAC/quadrotor/hen1.xml @@ -3,11 +3,11 @@ - + @@ -23,23 +23,23 @@ - + - + - + - - - - - + + + +
@@ -48,9 +48,9 @@ - - - + + +
@@ -62,25 +62,25 @@ - - - - + + + + - - - + + + - - - - + + + +
@@ -110,9 +110,9 @@ - + - +
@@ -146,76 +146,77 @@
- - - - + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - + - +
-
+
- - - - - - - - - - - - + + + + + + + + + + + + - + - +
+ - - - + + + @@ -227,9 +228,8 @@
- - - + +
diff --git a/conf/boards/apogee_1.0.makefile b/conf/boards/apogee_1.0.makefile new file mode 100644 index 0000000000..07639c1ccf --- /dev/null +++ b/conf/boards/apogee_1.0.makefile @@ -0,0 +1,58 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# apogee_1.0.makefile +# +# + +BOARD=apogee +BOARD_VERSION=1.0 +BOARD_CFG=\"boards/$(BOARD)_$(BOARD_VERSION).h\" + +ARCH=stm32 +ARCH_L=f4 +ARCH_DIR=stm32 +SRC_ARCH=arch/$(ARCH_DIR) +$(TARGET).ARCHDIR = $(ARCH) +$(TARGET).LDSCRIPT=$(SRC_ARCH)/apogee.ld + +HARD_FLOAT=yes + +# default flash mode is via usb dfu bootloader +# possibilities: DFU, SWD +FLASH_MODE ?= DFU +STLINK ?= y +DFU_UTIL ?= y + +# +# default LED configuration +# +RADIO_CONTROL_LED ?= 4 +BARO_LED ?= none +AHRS_ALIGNER_LED ?= 2 +GPS_LED ?= 3 +SYS_TIME_LED ?= 1 + +# +# default UART configuration (modem, gps, spektrum) +# + +MODEM_PORT ?= UART1 +MODEM_BAUD ?= B57600 + +GPS_PORT ?= UART4 +GPS_BAUD ?= B38400 + +RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT ?= UART2 + +SBUS_PORT ?= UART2 + +# +# default actuator configuration +# +# you can use different actuators by adding a configure option to your firmware section +# e.g. +# +ACTUATORS ?= actuators_pwm + diff --git a/conf/conf.xml.example b/conf/conf.xml.example index d3d1944b63..eac6d746c4 100644 --- a/conf/conf.xml.example +++ b/conf/conf.xml.example @@ -155,4 +155,14 @@ settings=" settings/fixedwing_basic.xml settings/control/ctl_energyadaptive.xml" gui_color="blue" /> + diff --git a/conf/firmwares/subsystems/shared/imu_aspirin_v2.1.makefile b/conf/firmwares/subsystems/shared/imu_aspirin_v2.1.makefile index 1e16703269..bcadf223b4 100644 --- a/conf/firmwares/subsystems/shared/imu_aspirin_v2.1.makefile +++ b/conf/firmwares/subsystems/shared/imu_aspirin_v2.1.makefile @@ -36,43 +36,7 @@ # # - -# for fixedwing firmware and ap only -ifeq ($(TARGET), ap) - IMU_ASPIRIN_2_CFLAGS = -DUSE_IMU -endif - -IMU_ASPIRIN_2_CFLAGS += -DIMU_TYPE_H=\"imu/imu_aspirin_2_spi.h\" -IMU_ASPIRIN_2_SRCS = $(SRC_SUBSYSTEMS)/imu.c -IMU_ASPIRIN_2_SRCS += $(SRC_SUBSYSTEMS)/imu/imu_aspirin_2_spi.c -IMU_ASPIRIN_2_SRCS += peripherals/mpu60x0.c -IMU_ASPIRIN_2_SRCS += peripherals/mpu60x0_spi.c - -# Magnetometer -#IMU_ASPIRIN_2_SRCS += peripherals/hmc58xx.c - -include $(CFG_SHARED)/spi_master.makefile - -ifeq ($(ARCH), lpc21) -IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI_SLAVE0 -IMU_ASPIRIN_2_CFLAGS += -DASPIRIN_2_SPI_SLAVE_IDX=SPI_SLAVE0 -IMU_ASPIRIN_2_CFLAGS += -DASPIRIN_2_SPI_DEV=spi1 -IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI1 -else ifeq ($(ARCH), stm32) -IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI2 -# Slave select configuration -# SLAVE2 is on PB12 (NSS) (MPU600 CS) -IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI_SLAVE2 -endif - -# 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 +include $(CFG_SHARED)/imu_aspirin_v2_common.makefile ap.CFLAGS += $(IMU_ASPIRIN_2_CFLAGS) ap.srcs += $(IMU_ASPIRIN_2_SRCS) - - -# -# NPS simulator -# -include $(CFG_SHARED)/imu_nps.makefile diff --git a/conf/firmwares/subsystems/shared/imu_aspirin_v2.2.makefile b/conf/firmwares/subsystems/shared/imu_aspirin_v2.2.makefile index 99968ac5a2..f9198a182c 100644 --- a/conf/firmwares/subsystems/shared/imu_aspirin_v2.2.makefile +++ b/conf/firmwares/subsystems/shared/imu_aspirin_v2.2.makefile @@ -2,13 +2,14 @@ # # Aspirin IMU v2.2 # -# actually identical with v2.1 since baro is not read in IMU driver +# nearly identical with v2.1, only has the MS5611 baro on SPI. +# The Baro CS line is # # # required xml: #
# -# +# # # # @@ -39,4 +40,18 @@ # -include $(CFG_SHARED)/imu_aspirin_v2.1.makefile +include $(CFG_SHARED)/imu_aspirin_v2_common.makefile + +# +# Baro is connected via SPI, so additionally specify the slave select line for it, +# so that it will be unselected at init (baro CS line high) +# +ifeq ($(ARCH), lpc21) +IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI_SLAVE1 +else ifeq ($(ARCH), stm32) +# SLAVE3 is on PC13, which is the baro CS +IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI_SLAVE3 +endif + +ap.CFLAGS += $(IMU_ASPIRIN_2_CFLAGS) +ap.srcs += $(IMU_ASPIRIN_2_SRCS) diff --git a/conf/firmwares/subsystems/shared/imu_aspirin_v2_common.makefile b/conf/firmwares/subsystems/shared/imu_aspirin_v2_common.makefile new file mode 100644 index 0000000000..150a6f0bac --- /dev/null +++ b/conf/firmwares/subsystems/shared/imu_aspirin_v2_common.makefile @@ -0,0 +1,72 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# Common part for Aspirin IMU v2.1 and v2.2 +# +# +# required xml: +#
+# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +#
+# +# + + +# for fixedwing firmware and ap only +ifeq ($(TARGET), ap) + IMU_ASPIRIN_2_CFLAGS = -DUSE_IMU +endif + +IMU_ASPIRIN_2_CFLAGS += -DIMU_TYPE_H=\"imu/imu_aspirin_2_spi.h\" +IMU_ASPIRIN_2_SRCS = $(SRC_SUBSYSTEMS)/imu.c +IMU_ASPIRIN_2_SRCS += $(SRC_SUBSYSTEMS)/imu/imu_aspirin_2_spi.c +IMU_ASPIRIN_2_SRCS += peripherals/mpu60x0.c +IMU_ASPIRIN_2_SRCS += peripherals/mpu60x0_spi.c + +include $(CFG_SHARED)/spi_master.makefile + +ifeq ($(ARCH), lpc21) +IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI_SLAVE0 +IMU_ASPIRIN_2_CFLAGS += -DASPIRIN_2_SPI_SLAVE_IDX=SPI_SLAVE0 +IMU_ASPIRIN_2_CFLAGS += -DASPIRIN_2_SPI_DEV=spi1 +IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI1 +else ifeq ($(ARCH), stm32) +IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI2 +# Slave select configuration +# SLAVE2 is on PB12 (NSS) (MPU600 CS) +IMU_ASPIRIN_2_CFLAGS += -DUSE_SPI_SLAVE2 +endif + +# Keep CFLAGS/Srcs for imu in separate expression so we can assign it to other targets +# and re-use that in the imu_aspirin_v2.1 and imu_aspirin_v2.2 makefiles + + +# +# NPS simulator +# +include $(CFG_SHARED)/imu_nps.makefile diff --git a/conf/firmwares/subsystems/shared/radio_control_sbus.makefile b/conf/firmwares/subsystems/shared/radio_control_sbus.makefile new file mode 100644 index 0000000000..2e8e9ecbe1 --- /dev/null +++ b/conf/firmwares/subsystems/shared/radio_control_sbus.makefile @@ -0,0 +1,20 @@ +# +# Makefile for shared radio_control SBUS subsystem +# + +$(TARGET).CFLAGS += -DRADIO_CONTROL +ifneq ($(RADIO_CONTROL_LED),none) + ap.CFLAGS += -DRADIO_CONTROL_LED=$(RADIO_CONTROL_LED) +endif + +# convert SBUS_PORT to upper and lower case strings: +SBUS_PORT_UPPER=$(shell echo $(SBUS_PORT) | tr a-z A-Z) +SBUS_PORT_LOWER=$(shell echo $(SBUS_PORT) | tr A-Z a-z) + +$(TARGET).CFLAGS += -DUSE_$(SBUS_PORT_UPPER) -D$(SBUS_PORT_UPPER)_BAUD=B100000 +$(TARGET).CFLAGS += -DSBUS_UART_DEV=$(SBUS_PORT_LOWER) +$(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_H=\"subsystems/radio_control/sbus.h\" +$(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_SBUS +$(TARGET).srcs += $(SRC_SUBSYSTEMS)/radio_control.c +$(TARGET).srcs += $(SRC_SUBSYSTEMS)/radio_control/sbus.c + diff --git a/conf/maps.xml.example b/conf/maps.xml.example index 0103dd0ef4..ea62c97c1e 100644 --- a/conf/maps.xml.example +++ b/conf/maps.xml.example @@ -1,3 +1,3 @@ - + diff --git a/conf/radios/T10CG_SBUS.xml b/conf/radios/T10CG_SBUS.xml new file mode 100644 index 0000000000..137caa7b20 --- /dev/null +++ b/conf/radios/T10CG_SBUS.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + diff --git a/data/maps/Makefile b/data/maps/Makefile index 13c26a90c6..03e3fcb5ef 100644 --- a/data/maps/Makefile +++ b/data/maps/Makefile @@ -28,7 +28,7 @@ $(DATADIR)/maps.google.com: $(DATADIR) FORCE exit 1) $(PAPARAZZI_HOME)/conf/maps.xml: $(DATADIR)/maps.google.com - $(eval GOOGLE_VERSION := $(shell grep -E "http://khm[0-9]+.google.com/kh/v=[0-9]+.x26" $(DATADIR)/maps.google.com | sed -E 's#.*http://khm[0-9]+.google.com/kh/v=##;s#.x26.*##')) + $(eval GOOGLE_VERSION := $(shell tr -s '[[:space:]]' '\n' < $(DATADIR)/maps.google.com | grep -E "http[s]?://khm[s]?[0-9]+.google.com/kh/v=[0-9]+.x26" | sed -E 's#.*http[s]?://khm[s]?[0-9]+.google.com/kh/v=##;s#.x26.*##')) $(eval $@_TMP := $(shell $(MKTEMP))) @echo "Updated google maps version to $(GOOGLE_VERSION)" @echo "-----------------------------------------------" diff --git a/data/pictures/Penguin.gif b/data/pictures/Penguin.gif new file mode 100644 index 0000000000..9e73bc08aa Binary files /dev/null and b/data/pictures/Penguin.gif differ diff --git a/sw/airborne/arch/lpc21/mcu_periph/uart_arch.c b/sw/airborne/arch/lpc21/mcu_periph/uart_arch.c index 125dac1c6f..f209085ce2 100644 --- a/sw/airborne/arch/lpc21/mcu_periph/uart_arch.c +++ b/sw/airborne/arch/lpc21/mcu_periph/uart_arch.c @@ -68,6 +68,10 @@ void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud) { uart_enable_interrupts(p); } +void uart_periph_set_bits_stop_parity(struct uart_periph* __attribute__((unused)) p, uint8_t __attribute__((unused)) bits, uint8_t __attribute__((unused)) stop, uint8_t __attribute__((unused)) parity) { + // TBD +} + void uart_transmit(struct uart_periph* p, uint8_t data ) { uint16_t temp; unsigned cpsr; diff --git a/sw/airborne/arch/stm32/mcu_periph/uart_arch.c b/sw/airborne/arch/stm32/mcu_periph/uart_arch.c index fb73f70983..335a90ed50 100644 --- a/sw/airborne/arch/stm32/mcu_periph/uart_arch.c +++ b/sw/airborne/arch/stm32/mcu_periph/uart_arch.c @@ -41,11 +41,8 @@ void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud) { - /* Configure USART */ + /* Configure USART baudrate */ usart_set_baudrate((uint32_t)p->reg_addr, baud); - usart_set_databits((uint32_t)p->reg_addr, 8); - usart_set_stopbits((uint32_t)p->reg_addr, USART_STOPBITS_1); - usart_set_parity((uint32_t)p->reg_addr, USART_PARITY_NONE); /* Disable Idle Line interrupt */ USART_CR1((uint32_t)p->reg_addr) &= ~USART_CR1_IDLEIE; @@ -61,6 +58,33 @@ void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud) { } +void uart_periph_set_bits_stop_parity(struct uart_periph* p, uint8_t bits, uint8_t stop, uint8_t parity) { + /* Configure USART parity and data bits */ + if (parity == UPARITY_EVEN) { + usart_set_parity((uint32_t)p->reg_addr, USART_PARITY_EVEN); + if (bits == UBITS_7) + usart_set_databits((uint32_t)p->reg_addr, 8); + else // 8 data bits by default + usart_set_databits((uint32_t)p->reg_addr, 9); + } + else if (parity == USART_PARITY_ODD) { + usart_set_parity((uint32_t)p->reg_addr, USART_PARITY_ODD); + if (bits == UBITS_7) + usart_set_databits((uint32_t)p->reg_addr, 8); + else // 8 data bits by default + usart_set_databits((uint32_t)p->reg_addr, 9); + } + else { // 8 data bist, NO_PARITY by default + usart_set_parity((uint32_t)p->reg_addr, USART_PARITY_NONE); + usart_set_databits((uint32_t)p->reg_addr, 8); // is 7bits without parity possible ? + } + /* Configure USART stop bits */ + if (stop == USTOP_2) + usart_set_stopbits((uint32_t)p->reg_addr, USART_STOPBITS_2); + else // 1 stop bit by default + usart_set_stopbits((uint32_t)p->reg_addr, USART_STOPBITS_1); +} + void uart_periph_set_mode(struct uart_periph* p, bool_t tx_enabled, bool_t rx_enabled, bool_t hw_flow_control) { uint32_t mode = 0; if (tx_enabled) @@ -173,6 +197,18 @@ static inline void usart_enable_irq(uint8_t IRQn) { #define UART1_HW_FLOW_CONTROL FALSE #endif +#ifndef UART1_BITS +#define UART1_BITS UBITS_8 +#endif + +#ifndef UART1_STOP +#define UART1_STOP USTOP_1 +#endif + +#ifndef UART1_PARITY +#define UART1_PARITY UPARITY_NO +#endif + void uart1_init( void ) { uart_periph_init(&uart1); @@ -201,7 +237,8 @@ void uart1_init( void ) { /* Configure USART1, enable hardware flow control*/ uart_periph_set_mode(&uart1, USE_UART1_TX, USE_UART1_RX, UART1_HW_FLOW_CONTROL); - /* Set USART1 baudrate and enable interrupt */ + /* Set USART1 parameters and enable interrupt */ + uart_periph_set_bits_stop_parity(&uart1, UART1_BITS, UART1_STOP, UART1_PARITY); uart_periph_set_baudrate(&uart1, UART1_BAUD); } @@ -224,6 +261,18 @@ void usart1_isr(void) { usart_isr(&uart1); } #define UART2_HW_FLOW_CONTROL FALSE #endif +#ifndef UART2_BITS +#define UART2_BITS UBITS_8 +#endif + +#ifndef UART2_STOP +#define UART2_STOP USTOP_1 +#endif + +#ifndef UART2_PARITY +#define UART2_PARITY UPARITY_NO +#endif + void uart2_init( void ) { uart_periph_init(&uart2); @@ -253,6 +302,7 @@ void uart2_init( void ) { uart_periph_set_mode(&uart2, USE_UART2_TX, USE_UART2_RX, UART2_HW_FLOW_CONTROL); /* Configure USART */ + uart_periph_set_bits_stop_parity(&uart2, UART2_BITS, UART2_STOP, UART2_PARITY); uart_periph_set_baudrate(&uart2, UART2_BAUD); } @@ -275,6 +325,18 @@ void usart2_isr(void) { usart_isr(&uart2); } #define UART3_HW_FLOW_CONTROL FALSE #endif +#ifndef UART3_BITS +#define UART3_BITS UBITS_8 +#endif + +#ifndef UART3_STOP +#define UART3_STOP USTOP_1 +#endif + +#ifndef UART3_PARITY +#define UART3_PARITY UPARITY_NO +#endif + void uart3_init( void ) { uart_periph_init(&uart3); @@ -304,6 +366,7 @@ void uart3_init( void ) { uart_periph_set_mode(&uart3, USE_UART3_TX, USE_UART3_RX, UART3_HW_FLOW_CONTROL); /* Configure USART */ + uart_periph_set_bits_stop_parity(&uart3, UART3_BITS, UART3_STOP, UART3_PARITY); uart_periph_set_baudrate(&uart3, UART3_BAUD); } @@ -322,6 +385,18 @@ void usart3_isr(void) { usart_isr(&uart3); } #define USE_UART4_RX TRUE #endif +#ifndef UART4_BITS +#define UART4_BITS UBITS_8 +#endif + +#ifndef UART4_STOP +#define UART4_STOP USTOP_1 +#endif + +#ifndef UART4_PARITY +#define UART4_PARITY UPARITY_NO +#endif + void uart4_init( void ) { uart_periph_init(&uart4); @@ -342,6 +417,7 @@ void uart4_init( void ) { /* Configure USART */ uart_periph_set_mode(&uart4, USE_UART4_TX, USE_UART4_RX, FALSE); + uart_periph_set_bits_stop_parity(&uart4, UART4_BITS, UART4_STOP, UART4_PARITY); uart_periph_set_baudrate(&uart4, UART4_BAUD); } @@ -360,6 +436,18 @@ void uart4_isr(void) { usart_isr(&uart4); } #define USE_UART5_RX TRUE #endif +#ifndef UART5_BITS +#define UART5_BITS UBITS_8 +#endif + +#ifndef UART5_STOP +#define UART5_STOP USTOP_1 +#endif + +#ifndef UART5_PARITY +#define UART5_PARITY UPARITY_NO +#endif + void uart5_init( void ) { uart_periph_init(&uart5); @@ -380,6 +468,7 @@ void uart5_init( void ) { /* Configure USART */ uart_periph_set_mode(&uart5, USE_UART5_TX, USE_UART5_RX, FALSE); + uart_periph_set_bits_stop_parity(&uart5, UART5_BITS, UART5_STOP, UART5_PARITY); uart_periph_set_baudrate(&uart5, UART5_BAUD); } @@ -402,6 +491,18 @@ void uart5_isr(void) { usart_isr(&uart5); } #define UART6_HW_FLOW_CONTROL FALSE #endif +#ifndef UART6_BITS +#define UART6_BITS UBITS_8 +#endif + +#ifndef UART6_STOP +#define UART6_STOP USTOP_1 +#endif + +#ifndef UART6_PARITY +#define UART6_PARITY UPARITY_NO +#endif + void uart6_init( void ) { uart_periph_init(&uart6); @@ -430,7 +531,7 @@ void uart6_init( void ) { /* Configure USART Tx,Rx and hardware flow control*/ uart_periph_set_mode(&uart6, USE_UART6_TX, USE_UART6_RX, UART6_HW_FLOW_CONTROL); - + uart_periph_set_bits_stop_parity(&uart6, UART6_BITS, UART6_STOP, UART6_PARITY); uart_periph_set_baudrate(&uart6, UART6_BAUD); } diff --git a/sw/airborne/boards/apogee_1.0.h b/sw/airborne/boards/apogee_1.0.h new file mode 100644 index 0000000000..78ff267397 --- /dev/null +++ b/sw/airborne/boards/apogee_1.0.h @@ -0,0 +1,399 @@ +#ifndef CONFIG_APOGEE_0_99_H +#define CONFIG_APOGEE_0_99_H + +#define BOARD_APOGEE + +/* Apogee has a 16MHz external clock and 168MHz internal. */ +#define EXT_CLK 16000000 +#define AHB_CLK 168000000 + +/* + * Onboard LEDs + */ + +/* red, on PC0 */ +#ifndef USE_LED_1 +#define USE_LED_1 1 +#endif +#define LED_1_GPIO GPIOC +#define LED_1_GPIO_CLK RCC_AHB1ENR_IOPCEN +#define LED_1_GPIO_PIN GPIO0 +#define LED_1_GPIO_ON gpio_clear +#define LED_1_GPIO_OFF gpio_set +#define LED_1_AFIO_REMAP ((void)0) + +/* orange, on PC13 */ +#ifndef USE_LED_2 +#define USE_LED_2 1 +#endif +#define LED_2_GPIO GPIOC +#define LED_2_GPIO_CLK RCC_AHB1ENR_IOPCEN +#define LED_2_GPIO_PIN GPIO13 +#define LED_2_GPIO_ON gpio_clear +#define LED_2_GPIO_OFF gpio_set +#define LED_2_AFIO_REMAP ((void)0) + +/* green, on PC1 */ +#ifndef USE_LED_3 +#define USE_LED_3 1 +#endif +#define LED_3_GPIO GPIOC +#define LED_3_GPIO_CLK RCC_AHB1ENR_IOPCEN +#define LED_3_GPIO_PIN GPIO1 +#define LED_3_GPIO_ON gpio_clear +#define LED_3_GPIO_OFF gpio_set +#define LED_3_AFIO_REMAP ((void)0) + +/* yellow, on PC3 */ +#ifndef USE_LED_4 +#define USE_LED_4 1 +#endif +#define LED_4_GPIO GPIOC +#define LED_4_GPIO_CLK RCC_AHB1ENR_IOPCEN +#define LED_4_GPIO_PIN GPIO3 +#define LED_4_GPIO_ON gpio_clear +#define LED_4_GPIO_OFF gpio_set +#define LED_4_AFIO_REMAP ((void)0) + +/* AUX1, on PB1, 1 on LED_ON, 0 on LED_OFF */ +#ifndef USE_LED_5 +#define USE_LED_5 0 +#endif +#define LED_5_GPIO GPIOB +#define LED_5_GPIO_CLK RCC_AHB1ENR_IOPBEN +#define LED_5_GPIO_PIN GPIO1 +#define LED_5_GPIO_ON gpio_set +#define LED_5_GPIO_OFF gpio_clear +#define LED_5_AFIO_REMAP ((void)0) + +/* AUX2, on PC5, 1 on LED_ON, 0 on LED_OFF */ +#ifndef USE_LED_6 +#define USE_LED_6 0 +#endif +#define LED_6_GPIO GPIOC +#define LED_6_GPIO_CLK RCC_AHB1ENR_IOPCEN +#define LED_6_GPIO_PIN GPIO5 +#define LED_6_GPIO_ON gpio_set +#define LED_6_GPIO_OFF gpio_clear +#define LED_6_AFIO_REMAP ((void)0) + +/* AUX3, on PC4, 1 on LED_ON, 0 on LED_OFF */ +#ifndef USE_LED_7 +#define USE_LED_7 0 +#endif +#define LED_7_GPIO GPIOC +#define LED_7_GPIO_CLK RCC_AHB1ENR_IOPCEN +#define LED_7_GPIO_PIN GPIO4 +#define LED_7_GPIO_ON gpio_set +#define LED_7_GPIO_OFF gpio_clear +#define LED_7_AFIO_REMAP ((void)0) + +/* AUX4, on PB15, 1 on LED_ON, 0 on LED_OFF */ +#ifndef USE_LED_8 +#define USE_LED_8 0 +#endif +#define LED_8_GPIO GPIOB +#define LED_8_GPIO_CLK RCC_AHB1ENR_IOPBEN +#define LED_8_GPIO_PIN GPIO15 +#define LED_8_GPIO_ON gpio_set +#define LED_8_GPIO_OFF gpio_clear +#define LED_8_AFIO_REMAP ((void)0) + +/* Power Switch, on PB12, 1 on LED_ON, 0 on LED_OFF */ +#ifndef USE_LED_9 +#define USE_LED_9 1 +#endif +#define LED_9_GPIO GPIOB +#define LED_9_GPIO_CLK RCC_AHB1ENR_IOPBEN +#define LED_9_GPIO_PIN GPIO12 +#define LED_9_GPIO_ON gpio_set +#define LED_9_GPIO_OFF gpio_clear +#define LED_9_AFIO_REMAP ((void)0) + +#define POWER_SWITCH_LED 9 + + +/* Pint to set Uart2 RX polarity, on PB13, output high inverts, low doesn't */ +#define RC_POLARITY_GPIO_PORT GPIOB +#define RC_POLARITY_GPIO_PIN GPIO13 + + +/* Default actuators driver */ +#define DEFAULT_ACTUATORS "subsystems/actuators/actuators_pwm.h" +#define ActuatorDefaultSet(_x,_y) ActuatorPwmSet(_x,_y) +#define ActuatorsDefaultInit() ActuatorsPwmInit() +#define ActuatorsDefaultCommit() ActuatorsPwmCommit() + +#define DefaultVoltageOfAdc(adc) (0.006185*adc) + +/* UART */ +#define UART1_GPIO_AF GPIO_AF7 +#define UART1_GPIO_PORT_RX GPIOA +#define UART1_GPIO_RX GPIO10 +#define UART1_GPIO_PORT_TX GPIOB +#define UART1_GPIO_TX GPIO6 + +#define UART2_GPIO_AF GPIO_AF7 +#define UART2_GPIO_PORT_RX GPIOA +#define UART2_GPIO_RX GPIO3 +#define USE_UART2_TX FALSE + +#define UART4_GPIO_AF GPIO_AF8 +#define UART4_GPIO_PORT_RX GPIOA +#define UART4_GPIO_RX GPIO1 +#define UART4_GPIO_PORT_TX GPIOA +#define UART4_GPIO_TX GPIO0 + +#define UART6_GPIO_AF GPIO_AF8 +#define UART6_GPIO_PORT_RX GPIOC +#define UART6_GPIO_RX GPIO7 +#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 + +#define BOARD_ADC_CHANNEL_1 9 +#define BOARD_ADC_CHANNEL_2 15 +#define BOARD_ADC_CHANNEL_3 14 +#define BOARD_ADC_CHANNEL_4 4 + +#ifndef USE_AD1 +#define USE_AD1 1 +#endif +/* provide defines that can be used to access the ADC_x in the code or airframe file + * these directly map to the index number of the 4 adc channels defined above + * 4th (index 3) is used for bat monitoring by default + */ +// AUX 1 +#define ADC_1 ADC1_C1 +#ifdef USE_ADC_1 +#ifndef ADC_1_GPIO_CLOCK_PORT +#define ADC_1_GPIO_CLOCK_PORT RCC_AHB1ENR_IOPBEN +#define ADC_1_INIT() gpio_mode_setup(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1) +#endif +#define USE_AD1_1 1 +#else +#define ADC_1_GPIO_CLOCK_PORT 0 +#define ADC_1_INIT() {} +#endif + +// AUX 2 +#define ADC_2 ADC1_C2 +#ifdef USE_ADC_2 +#ifndef ADC_2_GPIO_CLOCK_PORT +#define ADC_2_GPIO_CLOCK_PORT RCC_AHB1ENR_IOPCEN +#define ADC_2_INIT() gpio_mode_setup(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO5) +#endif +#define USE_AD1_2 1 +#else +#define ADC_2_GPIO_CLOCK_PORT 0 +#define ADC_2_INIT() {} +#endif + +// AUX 3 +#define ADC_3 ADC1_C3 +#ifdef USE_ADC_3 +#ifndef ADC_3_GPIO_CLOCK_PORT +#define ADC_3_GPIO_CLOCK_PORT RCC_AHB1ENR_IOPCEN +#define ADC_3_INIT() gpio_mode_setup(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO4) +#endif +#define USE_AD1_3 1 +#else +#define ADC_3_GPIO_CLOCK_PORT 0 +#define ADC_3_INIT() {} +#endif + +// BAT +#define ADC_4 ADC1_C4 +#ifndef ADC_4_GPIO_CLOCK_PORT +#define ADC_4_GPIO_CLOCK_PORT RCC_AHB1ENR_IOPAEN +#define ADC_4_INIT() gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO4) +#endif +#define USE_AD1_4 1 + +/* allow to define ADC_CHANNEL_VSUPPLY in the airframe file*/ +#ifndef ADC_CHANNEL_VSUPPLY +#define ADC_CHANNEL_VSUPPLY ADC_4 +#endif + +#define ADC_GPIO_CLOCK_PORT (ADC_1_GPIO_CLOCK_PORT | ADC_2_GPIO_CLOCK_PORT | ADC_3_GPIO_CLOCK_PORT | ADC_4_GPIO_CLOCK_PORT) + +/* GPIO mapping for ADC1 pins, overwrites the default in arch/stm32/mcu_periph/adc_arch.c */ +#ifdef USE_AD1 +#define ADC1_GPIO_INIT(gpio) { \ + ADC_1_INIT(); \ + ADC_2_INIT(); \ + ADC_3_INIT(); \ + ADC_4_INIT(); \ +} +#endif // USE_AD1 + + +/* I2C mapping */ +#define I2C1_GPIO_PORT GPIOB +#define I2C1_GPIO_SCL GPIO8 +#define I2C1_GPIO_SDA GPIO7 + +#define I2C2_GPIO_PORT GPIOB +#define I2C2_GPIO_SCL GPIO10 +#define I2C2_GPIO_SDA GPIO11 + + +/* Activate onboard baro */ +#define BOARD_HAS_BARO 1 + +/* PWM */ +#define PWM_USE_TIM2 1 +#define PWM_USE_TIM3 1 + +#define USE_PWM0 1 +#define USE_PWM1 1 +#define USE_PWM2 1 +#define USE_PWM3 1 +#define USE_PWM4 1 +#define USE_PWM5 1 + +// 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_IOPBEN +#define PWM_SERVO_0_GPIO GPIOB +#define PWM_SERVO_0_PIN GPIO0 +#define PWM_SERVO_0_AF GPIO_AF2 +#define PWM_SERVO_0_OC TIM_OC3 +#define PWM_SERVO_0_OC_BIT (1<<2) +#else +#define PWM_SERVO_0_OC_BIT 0 +#endif + +#if USE_PWM1 +#define PWM_SERVO_1 1 +#define PWM_SERVO_1_TIMER TIM2 +#define PWM_SERVO_1_RCC_IOP RCC_AHB1ENR_IOPAEN +#define PWM_SERVO_1_GPIO GPIOA +#define PWM_SERVO_1_PIN GPIO2 +#define PWM_SERVO_1_AF GPIO_AF1 +#define PWM_SERVO_1_OC TIM_OC3 +#define PWM_SERVO_1_OC_BIT (1<<2) +#else +#define PWM_SERVO_1_OC_BIT 0 +#endif + +#if USE_PWM2 +#define PWM_SERVO_2 2 +#define PWM_SERVO_2_TIMER TIM3 +#define PWM_SERVO_2_RCC_IOP RCC_AHB1ENR_IOPBEN +#define PWM_SERVO_2_GPIO GPIOB +#define PWM_SERVO_2_PIN GPIO5 +#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_TIMER TIM3 +#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 + +#if USE_PWM4 +#define PWM_SERVO_4 4 +#define PWM_SERVO_4_TIMER TIM2 +#define PWM_SERVO_4_RCC_IOP RCC_AHB1ENR_IOPBEN +#define PWM_SERVO_4_GPIO GPIOB +#define PWM_SERVO_4_PIN GPIO3 +#define PWM_SERVO_4_AF GPIO_AF1 +#define PWM_SERVO_4_OC TIM_OC2 +#define PWM_SERVO_4_OC_BIT (1<<1) +#else +#define PWM_SERVO_4_OC_BIT 0 +#endif + +#if USE_PWM5 +#define PWM_SERVO_5 5 +#define PWM_SERVO_5_TIMER TIM2 +#define PWM_SERVO_5_RCC_IOP RCC_AHB1ENR_IOPAEN +#define PWM_SERVO_5_GPIO GPIOA +#define PWM_SERVO_5_PIN GPIO15 +#define PWM_SERVO_5_AF GPIO_AF1 +#define PWM_SERVO_5_OC TIM_OC1 +#define PWM_SERVO_5_OC_BIT (1<<0) +#else +#define PWM_SERVO_5_OC_BIT 0 +#endif + +// PWM AUX1 (conflict with ADC0) +#if USE_PWM6 +#define PWM_SERVO_6 6 +#define PWM_SERVO_6_TIMER TIM3 +#define PWM_SERVO_6_RCC_IOP RCC_AHB1ENR_IOPBEN +#define PWM_SERVO_6_GPIO GPIOB +#define PWM_SERVO_6_PIN GPIO1 +#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 + + +#define PWM_TIM2_CHAN_MASK (PWM_SERVO_1_OC_BIT|PWM_SERVO_4_OC_BIT|PWM_SERVO_5_OC_BIT) +#define PWM_TIM3_CHAN_MASK (PWM_SERVO_0_OC_BIT|PWM_SERVO_2_OC_BIT|PWM_SERVO_3_OC_BIT|PWM_SERVO_6_OC_BIT) + +/* + * PPM + */ +#define USE_PPM_TIM1 1 + +#define PPM_CHANNEL TIM_IC1 +#define PPM_TIMER_INPUT TIM_IC_IN_TI1 +#define PPM_IRQ NVIC_TIM1_CC_IRQ +#define PPM_IRQ2 NVIC_TIM1_UP_TIM10_IRQ +// Capture/Compare InteruptEnable and InterruptFlag +#define PPM_CC_IE TIM_DIER_CC1IE +#define PPM_CC_IF TIM_SR_CC1IF +#define PPM_GPIO_PORT GPIOA +#define PPM_GPIO_PIN GPIO8 +#define PPM_GPIO_AF GPIO_AF1 + +/* + * Spektrum + */ +/* The line that is pulled low at power up to initiate the bind process */ +#define SPEKTRUM_BIND_PIN GPIO8 +#define SPEKTRUM_BIND_PIN_PORT GPIOA + +#define SPEKTRUM_UART2_RCC_REG &RCC_APB1ENR +#define SPEKTRUM_UART2_RCC_DEV RCC_APB1ENR_USART2EN +#define SPEKTRUM_UART2_BANK GPIOA +#define SPEKTRUM_UART2_PIN GPIO3 +#define SPEKTRUM_UART2_AF GPIO_AF7 +#define SPEKTRUM_UART2_IRQ NVIC_USART2_IRQ +#define SPEKTRUM_UART2_ISR usart2_isr +#define SPEKTRUM_UART2_DEV USART2 + +#endif /* CONFIG_APOGEE_0_99_H */ diff --git a/sw/airborne/boards/umarim/imu_umarim.c b/sw/airborne/boards/umarim/imu_umarim.c index 510b179161..e43024fac9 100644 --- a/sw/airborne/boards/umarim/imu_umarim.c +++ b/sw/airborne/boards/umarim/imu_umarim.c @@ -32,7 +32,7 @@ #include #include "imu_umarim.h" #include "mcu_periph/i2c.h" -#include "led.h" +#include "generated/airframe.h" // Downlink #include "mcu_periph/uart.h" @@ -40,6 +40,11 @@ #include "subsystems/datalink/downlink.h" +#ifndef UMARIM_ACCEL_RANGE +#define UMARIM_ACCEL_RANGE ADXL345_RANGE_16G +#endif +PRINT_CONFIG_VAR(UMARIM_ACCEL_RANGE) + #ifndef UMARIM_ACCEL_RATE #define UMARIM_ACCEL_RATE ADXL345_RATE_50HZ #endif @@ -71,6 +76,7 @@ void imu_impl_init(void) adxl345_i2c_init(&imu_umarim.adxl, &(IMU_UMARIM_I2C_DEV), ADXL345_ADDR_ALT); // change the default data rate imu_umarim.adxl.config.rate = UMARIM_ACCEL_RATE; + imu_umarim.adxl.config.range = UMARIM_ACCEL_RANGE; imu_umarim.gyr_valid = FALSE; imu_umarim.acc_valid = FALSE; diff --git a/sw/airborne/firmwares/fixedwing/datalink.c b/sw/airborne/firmwares/fixedwing/datalink.c index 0a14292fbe..d133fb5196 100644 --- a/sw/airborne/firmwares/fixedwing/datalink.c +++ b/sw/airborne/firmwares/fixedwing/datalink.c @@ -70,6 +70,9 @@ uint8_t joystick_block; } #endif +#if defined RADIO_CONTROL && defined RADIO_CONTROL_TYPE_DATALINK +#include "subsystems/radio_control/rc_datalink.h" +#endif #define MOfCm(_x) (((float)(_x))/100.) diff --git a/sw/airborne/firmwares/fixedwing/main_ap.c b/sw/airborne/firmwares/fixedwing/main_ap.c index ca3183a5e8..4455ca3641 100644 --- a/sw/airborne/firmwares/fixedwing/main_ap.c +++ b/sw/airborne/firmwares/fixedwing/main_ap.c @@ -157,6 +157,10 @@ void init_ap( void ) { mcu_init(); #endif /* SINGLE_MCU */ + /****** initialize and reset state interface ********/ + + stateInit(); + /************* Sensors initialization ***************/ #if USE_GPS gps_init(); @@ -184,8 +188,6 @@ void init_ap( void ) { ins_init(); - stateInit(); - /************* Links initialization ***************/ #if defined MCU_SPI_LINK || defined MCU_UART_LINK link_mcu_init(); diff --git a/sw/airborne/led.h b/sw/airborne/led.h index 46e8dc662f..f9aa9e2c55 100644 --- a/sw/airborne/led.h +++ b/sw/airborne/led.h @@ -74,6 +74,16 @@ static inline void led_init ( void ) { LED_OFF(8); #endif /* LED_8 */ +#if USE_LED_9 + LED_INIT(9); + LED_OFF(9); +#endif /* LED_9 */ + +#if USE_LED_10 + LED_INIT(10); + LED_OFF(10); +#endif /* LED_10 */ + #ifdef USE_LED_BODY LED_INIT(BODY); LED_OFF(BODY); diff --git a/sw/airborne/mcu_periph/uart.h b/sw/airborne/mcu_periph/uart.h index 1776ae2ca5..84fc1626a6 100644 --- a/sw/airborne/mcu_periph/uart.h +++ b/sw/airborne/mcu_periph/uart.h @@ -46,10 +46,21 @@ #define B19200 19200 #define B38400 38400 #define B57600 57600 +#define B100000 100000 #define B115200 115200 #define B230400 230400 #define B921600 921600 +#define UBITS_7 7 +#define UBITS_8 8 + +#define USTOP_1 1 +#define USTOP_2 2 + +#define UPARITY_NO 0 +#define UPARITY_ODD 1 +#define UPARITY_EVEN 2 + /** * UART peripheral */ @@ -75,6 +86,7 @@ struct uart_periph { extern void uart_periph_init(struct uart_periph* p); extern void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud); +extern void uart_periph_set_bits_stop_parity(struct uart_periph* p, uint8_t bits, uint8_t stop, uint8_t parity); extern void uart_periph_set_mode(struct uart_periph* p, bool_t tx_enabled, bool_t rx_enabled, bool_t hw_flow_control); extern void uart_transmit(struct uart_periph* p, uint8_t data); extern bool_t uart_check_free_space(struct uart_periph* p, uint8_t len); @@ -97,6 +109,7 @@ extern void uart0_init(void); #define UART0Getch() uart_getch(&uart0) #define UART0TxRunning uart0.tx_running #define UART0SetBaudrate(_b) uart_periph_set_baudrate(&uart0, _b) +#define UART0SetBitsStopParity(_b, _s, _p) uart_periph_set_bits_stop_parity(&uart0, _b, _s, _p) #endif // USE_UART0 @@ -112,6 +125,7 @@ extern void uart1_init(void); #define UART1Getch() uart_getch(&uart1) #define UART1TxRunning uart1.tx_running #define UART1SetBaudrate(_b) uart_periph_set_baudrate(&uart1, _b) +#define UART1SetBitsStopParity(_b, _s, _p) uart_periph_set_bits_stop_parity(&uart1, _b, _s, _p) #endif // USE_UART1 @@ -127,6 +141,7 @@ extern void uart2_init(void); #define UART2Getch() uart_getch(&uart2) #define UART2TxRunning uart2.tx_running #define UART2SetBaudrate(_b) uart_periph_set_baudrate(&uart2, _b) +#define UART2SetBitsStopParity(_b, _s, _p) uart_periph_set_bits_stop_parity(&uart2, _b, _s, _p) #endif // USE_UART2 @@ -142,6 +157,7 @@ extern void uart3_init(void); #define UART3Getch() uart_getch(&uart3) #define UART3TxRunning uart3.tx_running #define UART3SetBaudrate(_b) uart_periph_set_baudrate(&uart3, _b) +#define UART3SetBitsStopParity(_b, _s, _p) uart_periph_set_bits_stop_parity(&uart3, _b, _s, _p) #endif // USE_UART3 @@ -157,6 +173,7 @@ extern void uart4_init(void); #define UART4Getch() uart_getch(&uart4) #define UART4TxRunning uart4.tx_running #define UART4SetBaudrate(_b) uart_periph_set_baudrate(&uart4, _b) +#define UART4SetBitsStopParity(_b, _s, _p) uart_periph_set_bits_stop_parity(&uart4, _b, _s, _p) #endif // USE_UART4 @@ -172,6 +189,7 @@ extern void uart5_init(void); #define UART5Getch() uart_getch(&uart5) #define UART5TxRunning uart5.tx_running #define UART5SetBaudrate(_b) uart_periph_set_baudrate(&uart5, _b) +#define UART5SetBitsStopParity(_b, _s, _p) uart_periph_set_bits_stop_parity(&uart5, _b, _s, _p) #endif // USE_UART5 @@ -187,6 +205,7 @@ extern void uart6_init(void); #define UART6Getch() uart_getch(&uart6) #define UART6TxRunning uart6.tx_running #define UART6SetBaudrate(_b) uart_periph_set_baudrate(&uart6, _b) +#define UART6SetBitsStopParity(_b, _s, _p) uart_periph_set_bits_stop_parity(&uart6, _b, _s, _p) #endif // USE_UART6 diff --git a/sw/airborne/sd_card/main.c b/sw/airborne/sd_card/main.c deleted file mode 100644 index 37da825c60..0000000000 --- a/sw/airborne/sd_card/main.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "std.h" -#include "mcu.h" -#include "mcu_periph/sys_time.h" -#include "led.h" -#include "mcu_periph/uart.h" - -#include "messages.h" -#include "subsystems/datalink/downlink.h" - -#include "subsystems/datalink/datalink.h" -#include "generated/settings.h" -#include "dl_protocol.h" - -#include "mcu_periph/spi.h" -#include "sd_card.h" - -static inline void main_init( void ); -static inline void main_periodic_task( void ); -static inline void main_event_task( void ); - - -uint8_t dl_buffer[MSG_SIZE] __attribute__ ((aligned)); -bool_t dl_msg_available; -uint16_t datalink_time; - -int main( void ) { - main_init(); - while(1) { - if (sys_time_check_and_ack_timer(0)) - main_periodic_task(); - main_event_task( ); - } - return 0; -} - -static inline void main_init( void ) { - mcu_init(); - sys_time_register_timer((1./PERIODIC_FREQUENCY), NULL); - led_init(); - uart_init(&uart0); - - spi_init(); - sd_card_init(); - - mcu_int_enable(); -} - -static inline void main_periodic_task( void ) { - LED_TOGGLE(1); - //DOWNLINK_SEND_DEBUG(3,buf_input); -} - -static inline void main_event_task( void ) { - DatalinkEvent(); - - // spi event - if (spi_message_received) { - /* Got a message on SPI. */ - spi_message_received = FALSE; - sd_card_event(); - } - -} - - -#define IdOfMsg(x) (x[1]) - -void dl_parse_msg(void) { - - LED_TOGGLE(1); - - uint8_t msg_id = IdOfMsg(dl_buffer); - switch (msg_id) { - - case DL_PING: { - DOWNLINK_SEND_PONG(); - break; - } - - case DL_SETTING : { - uint8_t i = DL_SETTING_index(dl_buffer); - float var = DL_SETTING_value(dl_buffer); - DlSetting(i, var); - DOWNLINK_SEND_DL_VALUE(&i, &var); - break; - } - - } -} - - diff --git a/sw/airborne/sd_card/sd_card.c b/sw/airborne/sd_card/sd_card.c deleted file mode 100644 index 6ca1442682..0000000000 --- a/sw/airborne/sd_card/sd_card.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2007 ENAC - * - * 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 - * \brief - * - */ - -#include "sd_card.h" -#include "spi.h" - -bool_t sd_card_available; - -static bool_t status_read_data; - -#define CMD_INIT_1 0x24 // set chanel AIN1/AIN2 and next operation on filter high -#define CMD_INIT_2 0xCF // set unipolar mode, 24 bits, no boost, filter high -#define CMD_INIT_3 0x34 // set chanel AIN1/AIN2 and next operation on filter low -#define CMD_INIT_4 0x00 // set low filter -#define CMD_INIT_5 0x14 // set chanel AIN1/AIN2 and next operation on mode register -#define CMD_INIT_6 0x20 // set gain to 1, burnout current off, no filter sync, self calibration -#define CMD_MEASUREMENT 0x54 // set chanel AIN1/AIN2 and next operation on data register - - -uint8_t buf_input[3]; -uint8_t buf_output[3]; - - -static void send1_on_spi(uint8_t d) { - buf_output[0] = d; - spi_buffer_length = 1; - - spi_buffer_input = (uint8_t*)&buf_input; - spi_buffer_output = (uint8_t*)&buf_output; - SpiStart(); -} - - -void sd_card_init( void ) { - - send1_on_spi(CMD_INIT_1); - send1_on_spi(CMD_INIT_2); - send1_on_spi(CMD_INIT_3); - send1_on_spi(CMD_INIT_4); - send1_on_spi(CMD_INIT_5); - send1_on_spi(CMD_INIT_6); - - status_read_data = FALSE; - sd_card_available = FALSE; - -} - -void sd_card_periodic(void) { - if (!SpiCheckAvailable()) { - SpiOverRun(); - return; - } - - if (status_read_data) { - buf_output[0] = buf_output[1] = buf_output[2] = 0; - spi_buffer_length = 3; - } - else { - buf_output[0] = CMD_MEASUREMENT; - spi_buffer_length = 1; - } - - spi_buffer_input = (uint8_t*)&buf_input; - spi_buffer_output = (uint8_t*)&buf_output; - //if (status_read_data) - // SpiSetCPHA(); - //else - // SpiClrCPHA(); - SpiStart(); -} - -/* Handle the SPI message, i.e. store the received values in variables */ -void sd_card_event( void ) { - - if (status_read_data) { - } /* else nothing to read */ - - status_read_data = !status_read_data; - -} - diff --git a/sw/airborne/sd_card/sd_card.h b/sw/airborne/sd_card/sd_card.h deleted file mode 100644 index c74930ca38..0000000000 --- a/sw/airborne/sd_card/sd_card.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2007 ENAC - * - * 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 - * \brief - * - */ - -#include "std.h" - -extern uint8_t buf_input[3]; -extern uint8_t buf_output[3]; - -extern bool_t sd_card_available; - -extern void sd_card_init(void); -extern void sd_card_periodic(void); -extern void sd_card_event(void); - diff --git a/sw/airborne/subsystems/ahrs/ahrs_float_dcm.c b/sw/airborne/subsystems/ahrs/ahrs_float_dcm.c index 1a08c8bdae..dd990c34eb 100644 --- a/sw/airborne/subsystems/ahrs/ahrs_float_dcm.c +++ b/sw/airborne/subsystems/ahrs/ahrs_float_dcm.c @@ -20,7 +20,6 @@ * Theory: http://code.google.com/p/gentlenav/downloads/list file DCMDraft2.pdf * * Options: - * - USE_HIGH_ACCEL_FLAG: no compensation when high accelerations present * - USE_MAGNETOMETER_ONGROUND: use magnetic compensation before takeoff only while GPS course not good * - USE_AHRS_GPS_ACCELERATIONS: forward acceleration compensation from GPS speed * @@ -111,18 +110,6 @@ int renorm_blowup_count = 0; float imu_health = 0.; #endif -#if USE_HIGH_ACCEL_FLAG -// High Accel Flag -#define HIGH_ACCEL_LOW_SPEED 15.0 -#define HIGH_ACCEL_LOW_SPEED_RESUME 4.0 // Hysteresis -#define HIGH_ACCEL_HIGH_THRUST (0.8*MAX_PPRZ) -#define HIGH_ACCEL_HIGH_THRUST_RESUME (0.1*MAX_PPRZ) // Hysteresis -bool_t high_accel_done; -bool_t high_accel_flag; -// Command vector for thrust (fixed_wing) -#include "inter_mcu.h" -#endif - static inline void set_dcm_matrix_from_rmat(struct FloatRMat *rmat) { @@ -152,11 +139,6 @@ void ahrs_init(void) { /* set inital filter dcm */ set_dcm_matrix_from_rmat(&ahrs_impl.body_to_imu_rmat); -#if USE_HIGH_ACCEL_FLAG - high_accel_done = FALSE; - high_accel_flag = FALSE; -#endif - ahrs_impl.gps_speed = 0; ahrs_impl.gps_acceleration = 0; ahrs_impl.gps_course = 0; @@ -434,25 +416,6 @@ void Drift_correction(void) // Weight for accelerometer info (<0.5G = 0.0, 1G = 1.0 , >1.5G = 0.0) Accel_weight = Chop(1 - 2*fabs(1 - Accel_magnitude),0,1); // -#if USE_HIGH_ACCEL_FLAG - // Test for high acceleration: - // - low speed - // - high thrust - float speed = *stateGetHorizontalSpeedNorm_f(); - if (speed < HIGH_ACCEL_LOW_SPEED && ap_state->commands[COMMAND_THROTTLE] > HIGH_ACCEL_HIGH_THRUST && !high_accel_done) { - high_accel_flag = TRUE; - } else { - high_accel_flag = FALSE; - if (speed > HIGH_ACCEL_LOW_SPEED && !high_accel_done) { - high_accel_done = TRUE; // After takeoff, don't use high accel before landing (GS small, Throttle small) - } - if (speed < HIGH_ACCEL_HIGH_THRUST_RESUME && ap_state->commands[COMMAND_THROTTLE] < HIGH_ACCEL_HIGH_THRUST_RESUME) { - high_accel_done = FALSE; // Activate high accel after landing - } - } - if (high_accel_flag) { Accel_weight = 0.; } -#endif - #if PERFORMANCE_REPORTING == 1 { diff --git a/sw/airborne/subsystems/radio_control/sbus.c b/sw/airborne/subsystems/radio_control/sbus.c new file mode 100644 index 0000000000..726e0781c5 --- /dev/null +++ b/sw/airborne/subsystems/radio_control/sbus.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2013 Alexandre Bustico, 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, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** @file subsystems/radio_control/sbus.c + * + * Futaba SBUS decoder + */ + +#include "subsystems/radio_control.h" +#include "subsystems/radio_control/sbus.h" +#include BOARD_CONFIG +#include "mcu_periph/uart.h" +#include "mcu_periph/gpio.h" +#include + +/* + * SBUS protocol and state machine status + */ +#define SBUS_START_BYTE 0x0f +#define SBUS_END_BYTE 0x00 +#define SBUS_BIT_PER_CHANNEL 11 +#define SBUS_BIT_PER_BYTE 8 +#define SBUS_FLAGS_BYTE 22 +#define SBUS_FRAME_LOST_BIT 2 + +#define SBUS_STATUS_UNINIT 0 +#define SBUS_STATUS_GOT_START 1 + +/** Set polarity using RC_POLARITY_GPIO. + * SBUS signal has a reversed polarity compared to normal UART + * this allows to using hardware UART peripheral by changing + * the input signal polarity. + * Setting this gpio ouput high inverts the signal, + * output low sets it to normal polarity. + */ +#ifndef RC_SET_POLARITY +#define RC_SET_POLARITY gpio_output_high +#endif + + +/** SBUS struct */ +struct _sbus sbus; + +// Init function +void radio_control_impl_init(void) { + sbus.frame_available = FALSE; + sbus.status = SBUS_STATUS_UNINIT; + + // Set UART parameters (100K, 8 bits, 2 stops, even parity) + uart_periph_set_bits_stop_parity(&SBUS_UART_DEV, UBITS_8, USTOP_2, UPARITY_EVEN); + uart_periph_set_baudrate(&SBUS_UART_DEV, B100000); + + // Set polarity +#ifdef RC_POLARITY_GPIO_PORT + gpio_setup_output(RC_POLARITY_GPIO_PORT, RC_POLARITY_GPIO_PIN); + RC_SET_POLARITY(RC_POLARITY_GPIO_PORT, RC_POLARITY_GPIO_PIN); +#endif +} + + +/** Decode the raw buffer */ +static void decode_sbus_buffer (const uint8_t *src, uint16_t *dst, bool_t *available) +{ + // reset counters + uint8_t byteInRawBuf = 0; + uint8_t bitInRawBuf = 0; + uint8_t channel = 0; + uint8_t bitInChannel = 0; + + // clear bits + memset (dst, 0, SBUS_NB_CHANNEL*sizeof(uint16_t)); + + // decode sbus data + for (uint8_t i=0; i< (SBUS_NB_CHANNEL*SBUS_BIT_PER_CHANNEL); i++) { + if (src[byteInRawBuf] & (1< 0) { \ + radio_control.radio_ok_cpt--; \ + } else { \ + radio_control.status = RC_OK; \ + NormalizePpmIIR(sbus.pulses,radio_control); \ + _received_frame_handler(); \ + } \ + sbus.frame_available = FALSE; \ + } \ +} + +#endif /* RC_SBUS_H */ diff --git a/sw/tools/process_exif/README b/sw/tools/process_exif/README new file mode 100644 index 0000000000..9e41eab5a6 --- /dev/null +++ b/sw/tools/process_exif/README @@ -0,0 +1,67 @@ + +This is a script which loads GPS info into photo files (EXIF) based on the DC_SHOT messages +in the telemetry data. The .data file contains DC_SHOT messages (possibly not all emitted by telemetry, +but I'll get back to that later). This file together with the files in jpeg format are +copied to a processing directory, where this script extracts the GPS position from each DC_SHOT message +and edits the exif photo data in place, so effectively loads the GPS position into the EXIF data for +each photo. + +This script allows for gaps in DC_SHOT photo numbers and has some rudimentary error checking. + + +Instructions for use (on Ubuntu): + +1. Make sure python is installed. +2. Install the necessary python packages: + +# sudo apt-get install python-gdal +# sudo apt-get install gir1.2-gexiv2-0.4 + +3. Create a directory for processing. The photo's EXIF data will be edited in place. +4. Copy the .data file from the /var/log directory into this processing directory. +5. Copy all photos taken during the session to the directory. + +Verification: +- Sort photos by name. Since most cameras output the photo name with a number at the end, this should + show a list of photo names with consecutive numbers. +- Verify that the first photo corresponds to the first DC_SHOT message (photonr == 1). +- Add some dummy photos at the start to make up for any missing photos that may exist (such that they get + sorted before the real actual one). + +6. Run the script: + +# python sw/tools/process_exif/process_exif.py / + +Verification of processing: +- Look at the logs! These include the GPS positions calculated from UTM paparazzi positions. + It has been tested on the southern+western hemispheres, but not yet on eastern and northern hemispheres. +- Verify the tags in the photo: + exiftool -v2 /.jpg + +---- + +Considerations: + +The Ivy telemetry bus can get a little clogged up and this will result in discarded messages. This means that +not all DC_SHOT messages actually emitted by telemetry need to be there on the ground station, so some photos +won't have GPS coordinates loaded. Not all processing software for orthomosaics however require GPS positions +for all photos, for example if they rely on recognizing corresponding features in overlapping photos. + +Having more GPS coordinates in photos helps to improve accuracy, as the error in measurements approximates zero +over time if the error follows a normal distribution. + +Having many GPS coordinates is not enough however to achieve correct precision down to centimeters. Atmospheric conditions +need to be eliminated by applying 3-5 ground control points in strategic locations. These conditions can easily +cause the entire orthomosaic to be shifted over a meter. + + +If your processing software does require the GPS coordinates per photo, you need to look into the use of a +telemetry logger onboard. This logger can be hooked up separately on the tx+gnd lines of telemetry and "listen in" on +the connection. + + +The timing between actually taking a picture and the pulse event being sent is also an important consideration. +Obviously the GPS frequency is also an issue. If this is used on a fixedwing, obviously if the plane is underway +at 12m/s, 250ms will introduce a 3m bias on the position. Another reason to rely on GPS positions only as hints +and apply ground control points to "set" the orthomosaic to the right location. + diff --git a/sw/tools/process_exif/process_exif.py b/sw/tools/process_exif/process_exif.py new file mode 100644 index 0000000000..9394245504 --- /dev/null +++ b/sw/tools/process_exif/process_exif.py @@ -0,0 +1,166 @@ +#!/usr/bin/python +# +# +# +# +# +# +# +# +# +# +# +# +# +# + +# sudo apt-get install python-gdal +# sudo apt-get install gir1.2-gexiv2-0.4 + +from gi.repository import GExiv2 +import glob +import os +import re +import fnmatch +import sys +import math + +M_PI=3.14159265358979323846 +M_PI_2=(M_PI/2) +M_PI_4=(M_PI/4) + +def RadOfDeg( deg ): + return (deg / M_PI) * 180. + +# converts UTM coords to lat/long. Equations from USGS Bulletin 1532 +# East Longitudes are positive, West longitudes are negative. +# North latitudes are positive, South latitudes are negative +# Lat and Long are in decimal degrees. +# Written by Chuck Gantz- chuck.gantz@globalstar.com + +# ( I had some code here to use GDAL and which looked much simpler, but couldn't get that to work ) + +def UTMtoLL( northing, easting, utm_zone ): + + k0 = 0.9996; + a = 6378137; # WGS-84 + eccSquared = 0.00669438; # WGS-84 + e1 = (1-math.sqrt(1-eccSquared))/(1+math.sqrt(1-eccSquared)); + + x = easting - 500000.0; # remove 500,000 meter offset for longitude + y = northing; + + is_northern = northing < 0 + if ( not is_northern ): + y -= 10000000.0 # remove 10,000,000 meter offset used for southern hemisphere + + LongOrigin = (utm_zone - 1)*6 - 180 + 3; # +3 puts origin in middle of zone + + eccPrimeSquared = (eccSquared)/(1-eccSquared); + + M = y / k0; + mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256)); + + phi1Rad = mu + (3*e1/2-27*e1*e1*e1/32)*math.sin(2*mu) + (21*e1*e1/16-55*e1*e1*e1*e1/32)*math.sin(4*mu) +(151*e1*e1*e1/96)*math.sin(6*mu); + phi1 = RadOfDeg(phi1Rad); + + N1 = a/math.sqrt(1-eccSquared*math.sin(phi1Rad)*math.sin(phi1Rad)); + T1 = math.tan(phi1Rad)*math.tan(phi1Rad); + C1 = eccPrimeSquared*math.cos(phi1Rad)*math.cos(phi1Rad); + R1 = a*(1-eccSquared)/math.pow(1-eccSquared*math.sin(phi1Rad)*math.sin(phi1Rad), 1.5); + D = x/(N1*k0); + + Lat = phi1Rad - (N1*math.tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24+(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720); + Lat = RadOfDeg(Lat) + + Long = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)*D*D*D*D*D/120)/math.cos(phi1Rad) + Long = LongOrigin + RadOfDeg(Long) + + return Lat, Long + + +# At least the directory must be given +if len(sys.argv) < 2: + print "This script requires one argument: A directory containing photos and the paparazzi .data file" + sys.exit() + +path = str(sys.argv[ 1] ) + +if os.path.isdir(path) == False: + print "The indicated path '%s' is not a directory"%(path) + sys.exit() + +# Searching for all files with .data extension in indicated directory. +# It should only have one. +list_path = [i for i in os.listdir(path) if os.path.isfile(os.path.join(path, i))] +files = [os.path.join(path, j) for j in list_path if re.match(fnmatch.translate('*.data'), j, re.IGNORECASE)] + +if len(files) > 1: + print "Too many data files found. Only one is allowed." + sys.exit() + +if len(files) == 0: + print "No data files in 'data'. Copy data file there." + sys.exit() + +# Now searching for all photos (extension .jpg) in directory +list_path = [i for i in os.listdir(path) if os.path.isfile(os.path.join(path, i))] +photos = [os.path.join(path, j) for j in list_path if re.match(fnmatch.translate('*.jpg'), j, re.IGNORECASE)] + +# Photos must be sorted by number +photos.sort() + +# Opening the data file, iterating all lines and searching for DC_SHOT messages +f = open( files[0], 'r' ) +for line in f: + line = line.rstrip() + line = re.sub(' +',' ',line) + if 'DC_SHOT' in line: + # 618.710 1 DC_SHOT 212 29133350 -89510400 8.5 25 -9 29 0 0 385051650 + splitted = line.split( ' ' ) + + if len(splitted) < 12: + continue + try: + photonr = int(splitted[ 3 ]) + utm_east = ( float(int(splitted[ 4 ])) / 100. ) + utm_north = ( float(int(splitted[ 5 ])) / 100. ) + alt = float(splitted[ 6 ]) + utm_zone = int(splitted[ 7 ]) + phi = int(splitted[ 8 ]) + theta = int(splitted[ 9 ]) + course = int(splitted[ 10 ]) + speed = int(splitted[ 11 ]) + + lon, lat = UTMtoLL( utm_north, utm_east, utm_zone ) + + # Check that there as many photos and pick the indicated one. + # (this assumes the photos were taken correctly without a hiccup) + # It would never be able to check this anyway, since the camera could stall or + # not interpret the pulse? Leading to an incorrect GPS coordinate. + if len( photos ) < photonr: + print "Photo data %d found, but ran out of photos in directory"%(photonr) + continue + + # I've seen log files with -1 as DC_SHOT number due to an int8 I think. This should be + # fixed now, but just in case someone runs this on old data. + if (photonr < 0): + print "Negative photonr found." + continue + + # Pick out photo, open it through exiv2, + photoname = photos[ photonr - 1 ] + photo = GExiv2.Metadata( photoname ) + + photo.set_gps_info(lat, lon, alt) + photo.save_file() + + print "Photo %s and photonr %d merged. Lat/Lon/Alt: %f, %f, %f"%(photoname, photonr, lat, lon, alt) + + except ValueError as e: + print "Cannot read line: %s"%(line) + print "Value error(%s)"%(e) + continue + +print "Finished! exiting." +