diff --git a/.gitignore b/.gitignore index 08da500ec8..6a0bf36496 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,8 @@ # /sw/ground_segment/lpc21iap/ /sw/ground_segment/lpc21iap/lpc21iap +/sw/ground_segment/misc/ivy2serial + # /sw/ground_segment/multimon/ /sw/ground_segment/multimon/costabf.c /sw/ground_segment/multimon/mkcostab @@ -82,8 +84,9 @@ /sw/ground_segment/tmtc/ivy2udp /sw/ground_segment/tmtc/server /sw/ground_segment/tmtc/diadec -/sw/ground_segment/misc/ivy2serial +/sw/ground_segment/tmtc/ivy_serial_bridge /sw/ground_segment/tmtc/GSM/SMS_GS +/sw/ground_segment/tmtc/gpsd2ivy # /sw/ground_segment/joystick /sw/ground_segment/joystick/input2ivy diff --git a/conf/Makefile.lpc21 b/conf/Makefile.lpc21 index d69e1fad31..d29c7f2157 100644 --- a/conf/Makefile.lpc21 +++ b/conf/Makefile.lpc21 @@ -50,7 +50,6 @@ OBJCOPY = $(GCC_BIN_PREFIX)-objcopy OBJDUMP = $(GCC_BIN_PREFIX)-objdump NM = $(GCC_BIN_PREFIX)-nm SIZE = $(GCC_BIN_PREFIX)-size -OOCD = $(TOOLCHAIN_DIR)/bin/openocd # # If we can't find the toolchain (in /opt/paparazzi/arm-multilib or ~/sat) then try picking up the compilers from the path @@ -72,7 +71,15 @@ OBJCOPY = $(shell which $(GCC_PREFIX)-objcopy) OBJDUMP = $(shell which $(GCC_PREFIX)-objdump) NM = $(shell which $(GCC_PREFIX)-nm) SIZE = $(shell which $(GCC_PREFIX)-size) -OOCD = $(shell which openocd) +endif + +#first try to find OpenOCD in the path +OOCD = $(shell which openocd) +#if OpenOCD could not be found in the path, try the toolchain dir +ifeq ($(OOCD),) +ifneq ($(TOOLCHAIN),) +OOCD = $(shell if test -e $(TOOLCHAIN_DIR)/bin/openocd ; then echo $(TOOLCHAIN_DIR)/bin/openocd ; else echo "Warning: OpenOCD not found"; fi) +endif endif # Define some other programs and commands. @@ -182,7 +189,6 @@ LPC21IAP = $(PAPARAZZI_SRC)/sw/ground_segment/lpc21iap/lpc21iap # --------------------------------------------------------------------------- # Flash-Programming support using openocd -OOCD = openocd OOCD_INTERFACE = arm-usb-ocd OOCD_TARGET = csc diff --git a/conf/Makefile.stm32 b/conf/Makefile.stm32 index e9b22c3d0b..284ac27cdb 100644 --- a/conf/Makefile.stm32 +++ b/conf/Makefile.stm32 @@ -53,7 +53,6 @@ DMP = $(GCC_BIN_PREFIX)-objdump NM = $(GCC_BIN_PREFIX)-nm SIZE = $(GCC_BIN_PREFIX)-size RM = rm -OOCD = $(TOOLCHAIN_DIR)/bin/openocd # If we can't find the toolchain then try picking up the compilers from the path else @@ -63,10 +62,19 @@ CP = $(shell which arm-none-eabi-objcopy) DMP = $(shell which arm-none-eabi-objdump) NM = $(shell which arm-none-eabi-nm) SIZE = $(shell which arm-none-eabi-size) -OOCD = $(shell which openocd) GCC_LIB_DIR=$(shell dirname `which arm-none-eabi-gcc`)/../arm-none-eabi/lib endif +#first try to find OpenOCD in the path +OOCD = $(shell which openocd) +#if OpenOCD could not be found in the path, try the toolchain dir +ifeq ($(OOCD),) +ifneq ($(TOOLCHAIN),) +OOCD = $(shell if test -e $(TOOLCHAIN_DIR)/bin/openocd ; then echo $(TOOLCHAIN_DIR)/bin/openocd ; else echo "Warning: OpenOCD not found"; fi) +endif +endif + + LOADER=/home/poine/work/stm32/stm32loader-a3c51c26ad6c/stm32loader.py ifndef $(TARGET).OOCD_INTERFACE @@ -162,9 +170,9 @@ printcommands: @echo "Using SIZE = $(SIZE)" @echo "Using OOCD = $(OOCD)" @echo "GCC version:" - @$(CC) --version + @$(CC) --version | head -1 @echo "OOCD version:" - @$(OOCD) --version + @$(OOCD) --version | head -1 ifeq ("$(MULTILIB)","yes") printmultilib: diff --git a/conf/airframes/NoVa_L.xml b/conf/airframes/NoVa_L.xml index bdfeff07bf..4a8f9b0a4c 100644 --- a/conf/airframes/NoVa_L.xml +++ b/conf/airframes/NoVa_L.xml @@ -296,10 +296,10 @@ - - - - + + + + diff --git a/conf/airframes/Poine/booz2_a7.xml b/conf/airframes/Poine/booz2_a7.xml index 1ad69f0299..fe7afd9476 100644 --- a/conf/airframes/Poine/booz2_a7.xml +++ b/conf/airframes/Poine/booz2_a7.xml @@ -265,10 +265,10 @@ - - - - + + + + diff --git a/conf/airframes/Poine/booz2_a8.xml b/conf/airframes/Poine/booz2_a8.xml index dc4f14034d..46ad289276 100644 --- a/conf/airframes/Poine/booz2_a8.xml +++ b/conf/airframes/Poine/booz2_a8.xml @@ -193,24 +193,24 @@ - - - - - + + + + - + diff --git a/conf/airframes/Poine/swift_1.xml b/conf/airframes/Poine/swift_1.xml index 01f854892e..e736a7fe9d 100644 --- a/conf/airframes/Poine/swift_1.xml +++ b/conf/airframes/Poine/swift_1.xml @@ -29,7 +29,7 @@ - + diff --git a/conf/airframes/UofAdelaide/A1000_BOOZ.xml b/conf/airframes/UofAdelaide/A1000_BOOZ.xml index a5b9626618..54dbc672ca 100644 --- a/conf/airframes/UofAdelaide/A1000_BOOZ.xml +++ b/conf/airframes/UofAdelaide/A1000_BOOZ.xml @@ -272,7 +272,7 @@ second attempt - + diff --git a/conf/airframes/UofAdelaide/A1000_NOVA.xml b/conf/airframes/UofAdelaide/A1000_NOVA.xml index 434662d06f..761350b2c9 100644 --- a/conf/airframes/UofAdelaide/A1000_NOVA.xml +++ b/conf/airframes/UofAdelaide/A1000_NOVA.xml @@ -232,7 +232,7 @@ - + diff --git a/conf/airframes/esden/lisa_asctec.xml b/conf/airframes/esden/lisa_asctec.xml index dcb7e5c6db..b2a8c41b02 100644 --- a/conf/airframes/esden/lisa_asctec.xml +++ b/conf/airframes/esden/lisa_asctec.xml @@ -229,10 +229,10 @@ - - - - + + + + diff --git a/conf/airframes/esden/lisa_asctec_aspirin.xml b/conf/airframes/esden/lisa_asctec_aspirin.xml index 1fe9ba9e8b..67bad41320 100644 --- a/conf/airframes/esden/lisa_asctec_aspirin.xml +++ b/conf/airframes/esden/lisa_asctec_aspirin.xml @@ -231,10 +231,10 @@ - - - - + + + + diff --git a/conf/airframes/esden/lisa_pwm_aspirin.xml b/conf/airframes/esden/lisa_pwm_aspirin.xml index 086d309423..86ecf78dd6 100644 --- a/conf/airframes/esden/lisa_pwm_aspirin.xml +++ b/conf/airframes/esden/lisa_pwm_aspirin.xml @@ -232,10 +232,10 @@ - - - - + + + + diff --git a/conf/airframes/esden/synerani_4B.xml b/conf/airframes/esden/synerani_4B.xml index 982054537c..7b6827b926 100644 --- a/conf/airframes/esden/synerani_4B.xml +++ b/conf/airframes/esden/synerani_4B.xml @@ -235,10 +235,10 @@ - - - - + + + + diff --git a/conf/airframes/logger_sd.xml b/conf/airframes/logger_sd.xml new file mode 100644 index 0000000000..68ed0a2db5 --- /dev/null +++ b/conf/airframes/logger_sd.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + diff --git a/conf/airframes/mm/fixed-wing/drops.xml b/conf/airframes/mm/fixed-wing/drops.xml index a814fcbb9f..c14ba8ee72 100644 --- a/conf/airframes/mm/fixed-wing/drops.xml +++ b/conf/airframes/mm/fixed-wing/drops.xml @@ -28,7 +28,7 @@ - + diff --git a/conf/airframes/mm/fixed-wing/slowfast.xml b/conf/airframes/mm/fixed-wing/slowfast.xml index 5b6d5da9a9..67c62bfef9 100644 --- a/conf/airframes/mm/fixed-wing/slowfast.xml +++ b/conf/airframes/mm/fixed-wing/slowfast.xml @@ -27,7 +27,7 @@ - + diff --git a/conf/airframes/mm/fixed-wing/slowfast2.xml b/conf/airframes/mm/fixed-wing/slowfast2.xml index 9900e6c85b..d8833cad6c 100644 --- a/conf/airframes/mm/fixed-wing/slowfast2.xml +++ b/conf/airframes/mm/fixed-wing/slowfast2.xml @@ -28,15 +28,15 @@ - + - - + + diff --git a/conf/airframes/mm/rotor/qmk1.xml b/conf/airframes/mm/rotor/qmk1.xml index 2293a84efa..a210004acd 100644 --- a/conf/airframes/mm/rotor/qmk1.xml +++ b/conf/airframes/mm/rotor/qmk1.xml @@ -230,10 +230,10 @@ - - - - + + + + diff --git a/conf/airframes/osam_xsens_twog.xml b/conf/airframes/osam_xsens_twog.xml index 710f2e9451..ecbbaac663 100644 --- a/conf/airframes/osam_xsens_twog.xml +++ b/conf/airframes/osam_xsens_twog.xml @@ -25,7 +25,7 @@ - + diff --git a/conf/airframes/obsolete/logger_sd.xml b/conf/autopilot/logger.makefile similarity index 56% rename from conf/airframes/obsolete/logger_sd.xml rename to conf/autopilot/logger.makefile index 3da654143f..1845dd204b 100644 --- a/conf/airframes/obsolete/logger_sd.xml +++ b/conf/autopilot/logger.makefile @@ -1,62 +1,54 @@ - +# +# setup.makefile +# +# - +# default config +ifndef SPI_CHANNEL +SPI_CHANNEL = 1 +endif - +ifndef UART0_BAUD +UART0_BAUD = B9600 +endif - +ifndef UART1_BAUD +UART1_BAUD = B9600 +endif -CONFIG = \"tiny_2_1_1_usb.h\" -include $(PAPARAZZI_SRC)/conf/autopilot/tiny.makefile +# a configuration program to access both uart through usb +ifeq ($(ARCH), lpc21) -FLASH_MODE=IAP -ap.CFLAGS += -DBOARD_CONFIG=$(CONFIG) -DUSE_LED -ap.srcs = sys_time.c $(SRC_ARCH)/sys_time_hw.c $(SRC_ARCH)/armVIC.c main_logger.c +ap.CFLAGS += -DUSE_LED +ap.srcs = sys_time.c $(SRC_ARCH)/sys_time_hw.c $(SRC_ARCH)/armVIC.c $(SRC_FIRMWARE)/main_logger.c #choose one ap.CFLAGS += -DLOG_XBEE #ap.CFLAGS += -DLOG_PPRZ + #set the speed -ap.CFLAGS += -DUSE_UART0 -DUART0_BAUD=B9600 -DUSE_UART0_RX_ONLY -ap.CFLAGS += -DUSE_UART1 -DUART1_BAUD=B9600 -DUSE_UART1_RX_ONLY +ap.CFLAGS += -DUSE_UART0 -DUART0_BAUD=$(UART0_BAUD) -DUSE_UART0_RX_ONLY +ap.CFLAGS += -DUSE_UART1 -DUART1_BAUD=$(UART1_BAUD) -DUSE_UART1_RX_ONLY ap.srcs += $(SRC_ARCH)/mcu_periph/uart_arch.c +ap.srcs += mcu_periph/uart.c +ap.srcs += $(SRC_ARCH)/mcu_arch.c +ap.srcs += mcu.c #set SPI interface for SD card (0 or 1) -ap.CFLAGS += -DHW_ENDPOINT_LPC2000_SPINUM=1 +ap.CFLAGS += -DHW_ENDPOINT_LPC2000_SPINUM=$(SPI_CHANNEL) #efsl ap.CFLAGS += -I $(SRC_ARCH)/efsl/inc -I $(SRC_ARCH)/efsl/conf @@ -84,7 +76,9 @@ ap.srcs += $(SRC_ARCH)/lpcusb/examples/msc_scsi.c ap.srcs += $(SRC_ARCH)/lpcusb/examples/blockdev_sd.c ap.srcs += $(SRC_ARCH)/lpcusb/examples/lpc2000_spi.c - - +else +$(error usb_tunnel currently only implemented for the lpc21) +endif + diff --git a/conf/autopilot/subsystems/fixedwing/radio_control_datalink.makefile b/conf/autopilot/subsystems/fixedwing/radio_control_datalink.makefile index 6e22edbcc0..6202acf1b8 100644 --- a/conf/autopilot/subsystems/fixedwing/radio_control_datalink.makefile +++ b/conf/autopilot/subsystems/fixedwing/radio_control_datalink.makefile @@ -11,11 +11,11 @@ endif ifeq ($(NORADIO), False) - $(TARGET).CFLAGS += -DRADIO_CONTROL - $(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_H=\"radio_control/rc_datalink.h\" - $(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_DATALINK - $(TARGET).srcs += $(SRC_SUBSYSTEMS)/radio_control.c - $(TARGET).srcs += $(SRC_SUBSYSTEMS)/radio_control/rc_datalink.c + $(TARGET).CFLAGS += -DRADIO_CONTROL + $(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_H=\"radio_control/rc_datalink.h\" + $(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_DATALINK + $(TARGET).srcs += $(SRC_SUBSYSTEMS)/radio_control.c + $(TARGET).srcs += $(SRC_SUBSYSTEMS)/radio_control/rc_datalink.c # arch only with sim target for compatibility (empty functions) - sim.srcs += $(SRC_ARCH)/subsystems/radio_control/rc_datalink.c + sim.srcs += $(SRC_ARCH)/subsystems/radio_control/rc_datalink.c endif diff --git a/conf/messages.xml b/conf/messages.xml index 9fb975e628..b83b4ac517 100644 --- a/conf/messages.xml +++ b/conf/messages.xml @@ -78,7 +78,7 @@ - + @@ -542,7 +542,11 @@ - + + + + + diff --git a/conf/modules/digital_cam_servo.xml b/conf/modules/digital_cam_servo.xml new file mode 100644 index 0000000000..c9ae4882c0 --- /dev/null +++ b/conf/modules/digital_cam_servo.xml @@ -0,0 +1,43 @@ + + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+ diff --git a/conf/modules/mcp355x.xml b/conf/modules/mcp355x.xml new file mode 100644 index 0000000000..f68b84c6fa --- /dev/null +++ b/conf/modules/mcp355x.xml @@ -0,0 +1,17 @@ + + + +
+ +
+ + + + + + + + +
+ + diff --git a/conf/modules/pwm_meas.xml b/conf/modules/pwm_meas.xml new file mode 100644 index 0000000000..40ebbac8e1 --- /dev/null +++ b/conf/modules/pwm_meas.xml @@ -0,0 +1,19 @@ + + + +
+ +
+ + + + + + + +
diff --git a/conf/modules/xtend_rssi.xml b/conf/modules/xtend_rssi.xml new file mode 100644 index 0000000000..a7ac87a74f --- /dev/null +++ b/conf/modules/xtend_rssi.xml @@ -0,0 +1,21 @@ + + + + +
+ +
+ + + + + + +
+ diff --git a/conf/settings/basic.xml b/conf/settings/basic.xml index 58e354bce5..aab93f8457 100644 --- a/conf/settings/basic.xml +++ b/conf/settings/basic.xml @@ -22,6 +22,7 @@ + diff --git a/conf/settings/basic_infrared.xml b/conf/settings/basic_infrared.xml index 2933dca3be..c19cdc299c 100644 --- a/conf/settings/basic_infrared.xml +++ b/conf/settings/basic_infrared.xml @@ -22,6 +22,7 @@ + diff --git a/conf/settings/basic_ins.xml b/conf/settings/basic_ins.xml index f11281ab82..afe5702b71 100644 --- a/conf/settings/basic_ins.xml +++ b/conf/settings/basic_ins.xml @@ -22,6 +22,7 @@ + diff --git a/conf/telemetry/default_fixedwing_imu_9k6.xml b/conf/telemetry/default_fixedwing_imu_9k6.xml index ee2f0f4e93..df79bb466c 100644 --- a/conf/telemetry/default_fixedwing_imu_9k6.xml +++ b/conf/telemetry/default_fixedwing_imu_9k6.xml @@ -3,19 +3,19 @@ - + - - + + - + - - + + @@ -23,13 +23,13 @@ - + - + diff --git a/doc/control_loops/fixedwing/diagram_auto_airspeed_loop.dia b/doc/control_loops/fixedwing/diagram_auto_airspeed_loop.dia new file mode 100644 index 0000000000..97f7475194 Binary files /dev/null and b/doc/control_loops/fixedwing/diagram_auto_airspeed_loop.dia differ diff --git a/sw/airborne/ap_downlink.h b/sw/airborne/ap_downlink.h index aa0d6757cf..9d3c00ee84 100644 --- a/sw/airborne/ap_downlink.h +++ b/sw/airborne/ap_downlink.h @@ -56,20 +56,20 @@ #define PERIODIC_SEND_ALIVE(_chan) DOWNLINK_SEND_ALIVE(_chan, 16, MD5SUM); -#define PERIODIC_SEND_BAT(_chan) { \ - uint16_t amps = (int16_t) (current/1000); \ - Downlink({ int16_t e = energy; \ - DOWNLINK_SEND_BAT(_chan, \ - &v_ctl_throttle_slewed, \ - &vsupply, \ - &s, \ - &estimator_flight_time, \ - &kill_throttle, \ - &block_time, \ - &stage_time, \ - &e); \ - }); \ -} +#define PERIODIC_SEND_BAT(_chan) { \ + int16_t amps = (int16_t) (current/10); \ + Downlink({ int16_t e = energy; \ + DOWNLINK_SEND_BAT(_chan, \ + &v_ctl_throttle_slewed, \ + &vsupply, \ + &s, \ + &estimator_flight_time, \ + &kill_throttle, \ + &block_time, \ + &stage_time, \ + &e); \ + }); \ + } #ifdef MCU_SPI_LINK #define PERIODIC_SEND_DEBUG_MCU_LINK(_chan) DOWNLINK_SEND_DEBUG_MCU_LINK(_chan, &link_mcu_nb_err, &link_mcu_fbw_nb_err, &mcu1_ppm_cpt); diff --git a/sw/airborne/arch/lpc21/mcu_periph/pwm_input_arch.c b/sw/airborne/arch/lpc21/mcu_periph/pwm_input_arch.c new file mode 100644 index 0000000000..37af6366f9 --- /dev/null +++ b/sw/airborne/arch/lpc21/mcu_periph/pwm_input_arch.c @@ -0,0 +1,150 @@ +/* $Id$ + * + * Copyright (C) 2011 The Paparazzi Team + * + * 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. + * + */ + +/** \brief handling of arm7 PWM input using a timer with capture + * + */ + +#include "mcu_periph/pwm_input_arch.h" + +#include "LPC21xx.h" +#include "interrupt_hw.h" + +//UPDATE THESE TO BE MORE ACCESSIBLE AND BE WARY OF EXISTING USAGE +//POSSIBLY MAKE MORE INPUTS ACCESSIBLE +#ifdef USE_PWM_INPUT1 +//INPUT CAPTURE CAP0.3 on P0.29 +#define PWM_INPUT1_PINSEL PINSEL1 +#define PWM_INPUT1_PINSEL_BIT 26 +#define PWM_INPUT1_PINSEL_VAL (0x2 << PWM_INPUT1_PINSEL_BIT) +#define PWM_INPUT1_PINSEL_MASK (0x3 <>(0xf-ADXL345_BW_RATE))),Adxl345Periodic()); - // Read HMC58XX at 50Hz (main loop for rotorcraft: 512Hz) - RunOnceEvery(10,hmc58xx_periodic()); + // Read HMC58XX at 100Hz (main loop for rotorcraft: 512Hz) + RunOnceEvery(5,Hmc58xxPeriodic()); //RunOnceEvery(20,imu_navgo_downlink_raw()); } diff --git a/sw/airborne/boards/navgo_1.0.h b/sw/airborne/boards/navgo_1.0.h index b9921b245c..da87c56b1c 100644 --- a/sw/airborne/boards/navgo_1.0.h +++ b/sw/airborne/boards/navgo_1.0.h @@ -51,6 +51,16 @@ #define DefaultVoltageOfAdc(adc) (0.01837*adc) +/* SPI (SSP) */ +#define SPI_SELECT_SLAVE0_PORT 0 +#define SPI_SELECT_SLAVE0_PIN 20 + +#define SPI1_DRDY_PINSEL PINSEL1 +#define SPI1_DRDY_PINSEL_BIT 0 +#define SPI1_DRDY_PINSEL_VAL 1 +#define SPI1_DRDY_EINT 0 +#define SPI1_DRDY_VIC_IT VIC_EINT0 + /* PWM0 (internal PWM5) */ /* P0.21 */ #define PWM0_PINSEL PINSEL1 @@ -65,4 +75,4 @@ #define BOARD_HAS_BARO -#endif /* CONFIG_UMARIM_V1_0_H */ +#endif /* CONFIG_NAVGO_V1_0_H */ diff --git a/sw/airborne/boards/umarim/imu_umarim.c b/sw/airborne/boards/umarim/imu_umarim.c index 91b5047f7b..7f53a5e118 100644 --- a/sw/airborne/boards/umarim/imu_umarim.c +++ b/sw/airborne/boards/umarim/imu_umarim.c @@ -69,10 +69,10 @@ void imu_impl_init(void) void imu_periodic( void ) { // Start reading the latest gyroscope data - itg3200_periodic(); + Itg3200Periodic(); // Start reading the latest accelerometer data - adxl345_periodic(); + Adxl345Periodic(); //RunOnceEvery(10,imu_umarim_downlink_raw()); } diff --git a/sw/airborne/mcu_periph/pwm_input.c b/sw/airborne/mcu_periph/pwm_input.c new file mode 100644 index 0000000000..2c8070470d --- /dev/null +++ b/sw/airborne/mcu_periph/pwm_input.c @@ -0,0 +1,34 @@ +/* + * Paparazzi $Id$ + * + * Copyright (C) 2011 The Paparazzi Team + * + * 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 mcu_periph/pwm_input.c + * \brief arch independent PWM input capture API */ + +#include "std.h" +#include "mcu_periph/pwm_input.h" + +volatile uint32_t pwm_input_duty_tics[PWM_INPUT_NB]; +volatile uint8_t pwm_input_duty_valid[PWM_INPUT_NB]; +volatile uint32_t pwm_input_period_tics[PWM_INPUT_NB]; +volatile uint8_t pwm_input_period_valid[PWM_INPUT_NB]; diff --git a/sw/airborne/mcu_periph/pwm_input.h b/sw/airborne/mcu_periph/pwm_input.h new file mode 100644 index 0000000000..28e97a26c1 --- /dev/null +++ b/sw/airborne/mcu_periph/pwm_input.h @@ -0,0 +1,49 @@ +/* + * Paparazzi $Id$ + * + * Copyright (C) 2011 The Paparazzi Team + * + * 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 mcu_periph/pwm_input.h + * \brief arch independent PWM input capture API */ + + +#ifndef PWM_INPUT_H +#define PWM_INPUT_H + +#ifdef USE_PWM_INPUT + +#include "std.h" +#include "mcu_periph/pwm_input_arch.h" + +#define PWM_PULSE_TYPE_ACTIVE_HIGH 0 +#define PWM_PULSE_TYPE_ACTIVE_LOW 1 + +extern volatile uint32_t pwm_input_duty_tics[PWM_INPUT_NB]; +extern volatile uint8_t pwm_input_duty_valid[PWM_INPUT_NB]; +extern volatile uint32_t pwm_input_period_tics[PWM_INPUT_NB]; +extern volatile uint8_t pwm_input_period_valid[PWM_INPUT_NB]; + +extern void pwm_input_init(void); + +#endif /* USE_PWM_INPUT */ + +#endif /* PWM_INPUT_H */ diff --git a/sw/airborne/modules/adcs/mcp355x.h b/sw/airborne/modules/adcs/mcp355x.h new file mode 100644 index 0000000000..aef4b3e25a --- /dev/null +++ b/sw/airborne/modules/adcs/mcp355x.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* driver for MCP3550/1/3 (Module wrapper) + */ + +#ifndef MCP355X_MODULE_H +#define MCP355X_MODULE_H + +#include "peripherals/mcp355x.h" + +#endif diff --git a/sw/airborne/modules/core/pwm_meas.c b/sw/airborne/modules/core/pwm_meas.c new file mode 100644 index 0000000000..c8252cb69b --- /dev/null +++ b/sw/airborne/modules/core/pwm_meas.c @@ -0,0 +1,38 @@ +/* + * $Id$ + * + * Copyright (C) 2011 The Paparazzi Team + * + * 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 pwm_meas.c + * + * Wrapper to access pwm_input mcu peripheral from other modules + */ + + +#include "modules/core/pwm_meas.h" +#include "mcu_periph/pwm_input.h" +#include "sys_time.h" + +void pwm_meas_init( void ) +{ + pwm_input_init(); +} diff --git a/sw/airborne/modules/core/pwm_meas.h b/sw/airborne/modules/core/pwm_meas.h new file mode 100644 index 0000000000..cd0346e31c --- /dev/null +++ b/sw/airborne/modules/core/pwm_meas.h @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * Copyright (C) 2011 The Paparazzi Team + * + * 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 pwm_meas.h + * + * Wrapper to access pwm_input mcu peripheral from other modules + */ + +#ifndef PWM_MEAS_H +#define PWM_MEAS_H + +void pwm_meas_init( void ); + +#endif diff --git a/sw/airborne/modules/datalink/xtend_rssi.c b/sw/airborne/modules/datalink/xtend_rssi.c new file mode 100644 index 0000000000..ddf650b9c5 --- /dev/null +++ b/sw/airborne/modules/datalink/xtend_rssi.c @@ -0,0 +1,70 @@ +/* + * $Id$ + * + * Copyright (C) 2011 The Paparazzi Team + * + * 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 xtend_rssi.c + * + * This measures the rssi pwm signal from a Digi XTend radio modem + * and sends a message with the info. + */ + + +#include "modules/datalink/xtend_rssi.h" +#include "mcu_periph/pwm_input.h" +#include "sys_time.h" + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif + +#include "mcu_periph/uart.h" +#include "messages.h" +#include "downlink.h" + +//from Digi XTend manual +#define XTEND_RSSI_PWM_PERIOD_USEC 8320 //rssi pwm period () in sys tics + +#define XTEND_RSSI_PWM_ARRAY_INDEX (XTEND_RSSI_PWM_INPUT_CHANNEL - 1) + +void xtend_rssi_periodic( void ) { + +/* get the last duty if valid then reset valid flag (this says if we got another pulse since the last one) + calculate the % and dB from the duty using datasheet specs + send the %, dB, datalink time +*/ + + uint32_t duty_tics = pwm_input_duty_tics[XTEND_RSSI_PWM_ARRAY_INDEX]; + uint8_t duty_percent = 0; + uint8_t rssi_dB_fade_margin = 0; //shows dB fade margin above rated minimum sensitivity + + if (pwm_input_duty_valid[XTEND_RSSI_PWM_ARRAY_INDEX]) + { + duty_percent = (duty_tics * 100) / SYS_TICS_OF_USEC(XTEND_RSSI_PWM_PERIOD_USEC); + rssi_dB_fade_margin = (2 * duty_percent + 10) / 3; //not sure if this is right, datasheet isn't very informative + pwm_input_duty_valid[XTEND_RSSI_PWM_ARRAY_INDEX] = FALSE; + } + DOWNLINK_SEND_XTEND_RSSI(DefaultChannel, + &datalink_time, + &rssi_dB_fade_margin, + &duty_percent ); +} diff --git a/sw/airborne/modules/datalink/xtend_rssi.h b/sw/airborne/modules/datalink/xtend_rssi.h new file mode 100644 index 0000000000..0f7eb12bfc --- /dev/null +++ b/sw/airborne/modules/datalink/xtend_rssi.h @@ -0,0 +1,37 @@ +/* + * $Id$ + * + * Copyright (C) 2011 The Paparazzi Team + * + * 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 xtend_rssi.h + * + * This measures the rssi pwm signal from a Digi XTend radio modem + * and sends a message with the info. + * + */ + +#ifndef XTEND_RSSI_H +#define XTEND_RSSI_H + +void xtend_rssi_periodic( void ); + +#endif \ No newline at end of file diff --git a/sw/airborne/modules/digital_cam/servo_cam_ctrl.c b/sw/airborne/modules/digital_cam/servo_cam_ctrl.c new file mode 100644 index 0000000000..c4a8b0ad21 --- /dev/null +++ b/sw/airborne/modules/digital_cam/servo_cam_ctrl.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2010 The Paparazzi Team + * + * 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 "servo_cam_ctrl.h" + +// Button Timer +uint8_t dc_timer; + + + + diff --git a/sw/airborne/modules/digital_cam/servo_cam_ctrl.h b/sw/airborne/modules/digital_cam/servo_cam_ctrl.h new file mode 100644 index 0000000000..abdc372f1f --- /dev/null +++ b/sw/airborne/modules/digital_cam/servo_cam_ctrl.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2010 The Paparazzi Team + * + * 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 servo_cam_ctrl.h + * \brief Digital Camera Control + * + * Provides the control of the shutter and the zoom of a digital camera + * through standard binary IOs of the board. + * + * Configuration: + * Since the API of led.h is used, connected pins must be defined as led + * numbers (usually in the airframe file): + * + * + * + * + * Related bank and pin must also be defined: + * + * + * The required initialization (dc_init()) and periodic (4Hz) process + * + */ + +#ifndef servo_cam_ctrl_H +#define servo_cam_ctrl_H + +// Include Standard Camera Control Interface +#include "dc.h" + +// Include Servo and airframe servo channels +#include "std.h" +#include "commands.h" +#include "generated/airframe.h" + +extern uint8_t dc_timer; + +static inline void servo_cam_ctrl_init(void) +{ + // Call common DC init + dc_init(); + + // Do LED specific DC init + dc_timer = 0; +} + +#define DC_PUSH(X) commands[X] = -MAX_PPRZ; +#define DC_RELEASE(X) commands[X] = MAX_PPRZ; + +#ifndef DC_SHUTTER_DELAY +#define DC_SHUTTER_DELAY 2 /* 4Hz -> 0.5s */ +#endif + +#ifndef DC_SHUTTER_SERVO +#error DC: Please specify at least a SHUTTER SERVO +#endif + +/* Command The Camera */ +static inline void dc_send_command(uint8_t cmd) +{ + dc_timer = DC_SHUTTER_DELAY; + switch (cmd) + { + case DC_SHOOT: + DC_PUSH(DC_SHUTTER_SERVO); + dc_send_shot_position(); + break; +#ifdef DC_ZOOM_IN_SERVO + case DC_TALLER: + DC_PUSH(DC_ZOOM_IN_SERVO); + break; +#endif +#ifdef DC_ZOOM_OUT_SERVO + case DC_WIDER: + DC_PUSH(DC_ZOOM_OUT_SERVO); + break; +#endif +#ifdef DC_POWER_SERVO + case DC_POWER: + DC_PUSH(DC_POWER_SERVO); + break; +#endif + } +} + + +/* 4Hz Periodic */ +static inline void servo_cam_ctrl_periodic( void ) +{ + if (dc_timer) { + dc_timer--; + } else { + DC_RELEASE(DC_SHUTTER_SERVO); +#ifdef DC_ZOOM_IN_SERVO + DC_RELEASE(DC_ZOOM_IN_SERVO); +#endif +#ifdef DC_ZOOM_OUT_SERVO + DC_RELEASE(DC_ZOOM_OUT_SERVO); +#endif +#ifdef DC_POWER_SERVO + DC_RELEASE(DC_POWER_SERVO); +#endif + } + + // Common DC Periodic task + dc_periodic_4Hz(); +} + + + + + +#endif // DC_H diff --git a/sw/airborne/peripherals/adxl345.extra_i2c.h b/sw/airborne/peripherals/adxl345.extra_i2c.h index 65985aaac0..aa9a4a9506 100644 --- a/sw/airborne/peripherals/adxl345.extra_i2c.h +++ b/sw/airborne/peripherals/adxl345.extra_i2c.h @@ -67,6 +67,8 @@ #define ADXL345_I2C_DEVICE i2c1 #endif +// Config done flag +extern bool_t adxl345_initialized; // Data ready flag extern volatile bool_t adxl345_data_available; // Data vector @@ -78,9 +80,16 @@ extern struct i2c_transaction adxl345_trans; // Functions extern void adxl345_init(void); -extern void adxl345_periodic(void); +extern void adxl345_configure(void); +extern void adxl345_read(void); extern void adxl345_event(void); +// Macro for using ADXL345 in periodic function +#define Adxl345Periodic() { \ + if (adxl345_initialized) adxl345_read(); \ + else adxl345_configure(); \ +} + #define AccelEvent(_handler) { \ adxl345_event(); \ if (adxl345_data_available) { \ diff --git a/sw/airborne/peripherals/adxl345.i2c.c b/sw/airborne/peripherals/adxl345.i2c.c index 378aa72655..85d968ea9a 100644 --- a/sw/airborne/peripherals/adxl345.i2c.c +++ b/sw/airborne/peripherals/adxl345.i2c.c @@ -62,21 +62,25 @@ static void adxl345_send_config(void) adxl345_i2c_trans.buf[0] = ADXL345_REG_BW_RATE; adxl345_i2c_trans.buf[1] = ADXL345_BW_RATE; I2CTransmit(ADXL345_I2C_DEVICE, adxl345_i2c_trans, ADXL345_I2C_ADDR, 2); + adxl345_init_status++; break; case ADXL_CONF_POWER: adxl345_i2c_trans.buf[0] = ADXL345_REG_POWER_CTL; adxl345_i2c_trans.buf[1] = ADXL345_POWER_CTL; I2CTransmit(ADXL345_I2C_DEVICE, adxl345_i2c_trans, ADXL345_I2C_ADDR, 2); + adxl345_init_status++; break; case ADXL_CONF_INT: adxl345_i2c_trans.buf[0] = ADXL345_REG_INT_ENABLE; adxl345_i2c_trans.buf[1] = ADXL345_INT_ENABLE; I2CTransmit(ADXL345_I2C_DEVICE, adxl345_i2c_trans, ADXL345_I2C_ADDR, 2); + adxl345_init_status++; break; case ADXL_CONF_FORMAT: adxl345_i2c_trans.buf[0] = ADXL345_REG_DATA_FORMAT; adxl345_i2c_trans.buf[1] = ADXL345_DATA_FORMAT; I2CTransmit(ADXL345_I2C_DEVICE, adxl345_i2c_trans, ADXL345_I2C_ADDR, 2); + adxl345_init_status++; break; case ADXL_CONF_DONE: adxl345_initialized = TRUE; @@ -87,24 +91,23 @@ static void adxl345_send_config(void) } } -void adxl345_periodic(void) +// Configure +void adxl345_configure(void) { - if (!adxl345_initialized) { - // Configure + if (adxl345_init_status == ADXL_CONF_UNINIT) { + adxl345_init_status++; if (adxl345_i2c_trans.status == I2CTransSuccess || adxl345_i2c_trans.status == I2CTransDone) { - adxl345_init_status++; adxl345_send_config(); } - if (adxl345_i2c_trans.status == I2CTransFailed) { - adxl345_send_config(); // Retry config - } } - else { - // Normal reading - if (adxl345_i2c_trans.status == I2CTransDone){ - adxl345_i2c_trans.buf[0] = ADXL345_REG_DATA_X0; - I2CTransceive(ADXL345_I2C_DEVICE, adxl345_i2c_trans, ADXL345_I2C_ADDR, 1, 6); - } +} + +// Normal reading +void adxl345_read(void) +{ + if (adxl345_initialized && adxl345_i2c_trans.status == I2CTransDone) { + adxl345_i2c_trans.buf[0] = ADXL345_REG_DATA_X0; + I2CTransceive(ADXL345_I2C_DEVICE, adxl345_i2c_trans, ADXL345_I2C_ADDR, 1, 6); } } @@ -125,6 +128,17 @@ void adxl345_event(void) adxl345_i2c_trans.status = I2CTransDone; } } + else if (!adxl345_initialized && adxl345_init_status != ADXL_CONF_UNINIT) { // Configuring + if (adxl345_i2c_trans.status == I2CTransSuccess || adxl345_i2c_trans.status == I2CTransDone) { + adxl345_i2c_trans.status = I2CTransDone; + adxl345_send_config(); + } + if (adxl345_i2c_trans.status == I2CTransFailed) { + adxl345_init_status--; + adxl345_i2c_trans.status = I2CTransDone; + adxl345_send_config(); // Retry config (TODO max retry) + } + } } diff --git a/sw/airborne/peripherals/hmc58xx.c b/sw/airborne/peripherals/hmc58xx.c index ee2d50022f..5235bc191a 100644 --- a/sw/airborne/peripherals/hmc58xx.c +++ b/sw/airborne/peripherals/hmc58xx.c @@ -61,16 +61,19 @@ static void hmc58xx_send_config(void) hmc58xx_i2c_trans.buf[0] = HMC58XX_REG_CFGA; hmc58xx_i2c_trans.buf[1] = HMC58XX_CRA; I2CTransmit(HMC58XX_I2C_DEVICE, hmc58xx_i2c_trans, HMC58XX_ADDR, 2); + hmc58xx_init_status++; break; case HMC_CONF_CRB: hmc58xx_i2c_trans.buf[0] = HMC58XX_REG_CFGB; hmc58xx_i2c_trans.buf[1] = HMC58XX_CRB; I2CTransmit(HMC58XX_I2C_DEVICE, hmc58xx_i2c_trans, HMC58XX_ADDR, 2); + hmc58xx_init_status++; break; case HMC_CONF_MODE: hmc58xx_i2c_trans.buf[0] = HMC58XX_REG_MODE; hmc58xx_i2c_trans.buf[1] = HMC58XX_MD; I2CTransmit(HMC58XX_I2C_DEVICE, hmc58xx_i2c_trans, HMC58XX_ADDR, 2); + hmc58xx_init_status++; break; case HMC_CONF_DONE: hmc58xx_initialized = TRUE; @@ -81,24 +84,23 @@ static void hmc58xx_send_config(void) } } -void hmc58xx_periodic(void) +// Configure +void hmc58xx_configure(void) { - if (!hmc58xx_initialized) { - // Configure + if (hmc58xx_init_status == HMC_CONF_UNINIT) { + hmc58xx_init_status++; if (hmc58xx_i2c_trans.status == I2CTransSuccess || hmc58xx_i2c_trans.status == I2CTransDone) { - hmc58xx_init_status++; hmc58xx_send_config(); } - if (hmc58xx_i2c_trans.status == I2CTransFailed) { - hmc58xx_send_config(); // Retry config - } } - else { - // Normal reading - if (hmc58xx_i2c_trans.status == I2CTransDone){ - hmc58xx_i2c_trans.buf[0] = HMC58XX_REG_DATXM; - I2CTransceive(HMC58XX_I2C_DEVICE, hmc58xx_i2c_trans, HMC58XX_ADDR, 1, 6); - } +} + +// Normal reading +void hmc58xx_read(void) +{ + if (hmc58xx_initialized && hmc58xx_i2c_trans.status == I2CTransDone){ + hmc58xx_i2c_trans.buf[0] = HMC58XX_REG_DATXM; + I2CTransceive(HMC58XX_I2C_DEVICE, hmc58xx_i2c_trans, HMC58XX_ADDR, 1, 6); } } @@ -118,5 +120,16 @@ void hmc58xx_event(void) hmc58xx_i2c_trans.status = I2CTransDone; } } + else if (!hmc58xx_initialized && hmc58xx_init_status != HMC_CONF_UNINIT) { // Configuring + if (hmc58xx_i2c_trans.status == I2CTransSuccess || hmc58xx_i2c_trans.status == I2CTransDone) { + hmc58xx_i2c_trans.status = I2CTransDone; + hmc58xx_send_config(); + } + if (hmc58xx_i2c_trans.status == I2CTransFailed) { + hmc58xx_init_status--; + hmc58xx_i2c_trans.status = I2CTransDone; + hmc58xx_send_config(); // Retry config (TODO max retry) + } + } } diff --git a/sw/airborne/peripherals/hmc58xx.h b/sw/airborne/peripherals/hmc58xx.h index 4dd01b6a83..1f4eae3e42 100644 --- a/sw/airborne/peripherals/hmc58xx.h +++ b/sw/airborne/peripherals/hmc58xx.h @@ -70,6 +70,8 @@ #define HMC58XX_I2C_DEVICE i2c2 #endif +// Config done flag +extern bool_t hmc58xx_initialized; // Data ready flag extern volatile bool_t hmc58xx_data_available; // Data vector @@ -81,9 +83,16 @@ extern struct i2c_transaction hmc58xx_i2c_trans; // Functions extern void hmc58xx_init(void); -extern void hmc58xx_periodic(void); +extern void hmc58xx_configure(void); +extern void hmc58xx_read(void); extern void hmc58xx_event(void); +// Macro for using HMC58XX in periodic function +#define Hmc58xxPeriodic() { \ + if (hmc58xx_initialized) hmc58xx_read(); \ + else hmc58xx_configure(); \ +} + #define MagEvent(_m_handler) { \ hmc58xx_event(); \ if (hmc58xx_data_available) { \ diff --git a/sw/airborne/peripherals/itg3200.c b/sw/airborne/peripherals/itg3200.c index 62a02211de..6c0c1ba6f6 100644 --- a/sw/airborne/peripherals/itg3200.c +++ b/sw/airborne/peripherals/itg3200.c @@ -62,21 +62,25 @@ static void itg3200_send_config(void) itg3200_i2c_trans.buf[0] = ITG3200_REG_SMPLRT_DIV; itg3200_i2c_trans.buf[1] = ITG3200_SMPLRT_DIV; I2CTransmit(ITG3200_I2C_DEVICE, itg3200_i2c_trans, ITG3200_I2C_ADDR, 2); + itg3200_init_status++; break; case ITG_CONF_DF: itg3200_i2c_trans.buf[0] = ITG3200_REG_DLPF_FS; itg3200_i2c_trans.buf[1] = ITG3200_DLPF_FS; I2CTransmit(ITG3200_I2C_DEVICE, itg3200_i2c_trans, ITG3200_I2C_ADDR, 2); + itg3200_init_status++; break; case ITG_CONF_INT: itg3200_i2c_trans.buf[0] = ITG3200_REG_INT_CFG; itg3200_i2c_trans.buf[1] = ITG3200_INT_CFG; I2CTransmit(ITG3200_I2C_DEVICE, itg3200_i2c_trans, ITG3200_I2C_ADDR, 2); + itg3200_init_status++; break; case ITG_CONF_PWR: itg3200_i2c_trans.buf[0] = ITG3200_REG_PWR_MGM; itg3200_i2c_trans.buf[1] = ITG3200_PWR_MGM; I2CTransmit(ITG3200_I2C_DEVICE, itg3200_i2c_trans, ITG3200_I2C_ADDR, 2); + itg3200_init_status++; break; case ITG_CONF_DONE: itg3200_initialized = TRUE; @@ -87,24 +91,23 @@ static void itg3200_send_config(void) } } -void itg3200_periodic(void) +// Configure +void itg3200_configure(void) { - if (!itg3200_initialized) { - // Configure + if (itg3200_init_status == ITG_CONF_UNINIT) { + itg3200_init_status++; if (itg3200_i2c_trans.status == I2CTransSuccess || itg3200_i2c_trans.status == I2CTransDone) { - itg3200_init_status++; itg3200_send_config(); } - if (itg3200_i2c_trans.status == I2CTransFailed) { - itg3200_send_config(); // Retry config - } } - else { - // Normal reading - if (itg3200_i2c_trans.status == I2CTransDone) { - itg3200_i2c_trans.buf[0] = ITG3200_REG_INT_STATUS; - I2CTransceive(ITG3200_I2C_DEVICE, itg3200_i2c_trans, ITG3200_I2C_ADDR, 1, 9); - } +} + +// Normal reading +void itg3200_read(void) +{ + if (itg3200_initialized && itg3200_i2c_trans.status == I2CTransDone) { + itg3200_i2c_trans.buf[0] = ITG3200_REG_INT_STATUS; + I2CTransceive(ITG3200_I2C_DEVICE, itg3200_i2c_trans, ITG3200_I2C_ADDR, 1, 9); } } @@ -128,5 +131,16 @@ void itg3200_event(void) itg3200_i2c_trans.status = I2CTransDone; } } + else if (!itg3200_initialized && itg3200_init_status != ITG_CONF_UNINIT) { // Configuring + if (itg3200_i2c_trans.status == I2CTransSuccess || itg3200_i2c_trans.status == I2CTransDone) { + itg3200_i2c_trans.status = I2CTransDone; + itg3200_send_config(); + } + if (itg3200_i2c_trans.status == I2CTransFailed) { + itg3200_init_status--; + itg3200_i2c_trans.status = I2CTransDone; + itg3200_send_config(); // Retry config (TODO max retry) + } + } } diff --git a/sw/airborne/peripherals/itg3200.extra.h b/sw/airborne/peripherals/itg3200.extra.h index 5bfb5bb95f..ba4d761eec 100644 --- a/sw/airborne/peripherals/itg3200.extra.h +++ b/sw/airborne/peripherals/itg3200.extra.h @@ -64,6 +64,8 @@ #define ITG3200_I2C_DEVICE i2c1 #endif +// Config done flag +extern bool_t itg3200_initialized; // Data ready flag extern volatile bool_t itg3200_data_available; // Data vector @@ -75,9 +77,16 @@ extern struct i2c_transaction itg3200_trans; // Functions extern void itg3200_init(void); -extern void itg3200_periodic(void); +extern void itg3200_configure(void); +extern void itg3200_read(void); extern void itg3200_event(void); +// Macro for using ITG3200 in periodic function +#define Itg3200Periodic() { \ + if (itg3200_initialized) itg3200_read(); \ + else itg3200_configure(); \ +} + #define GyroEvent(_handler) { \ itg3200_event(); \ if (itg3200_data_available) { \ diff --git a/sw/airborne/peripherals/mcp355x.c b/sw/airborne/peripherals/mcp355x.c new file mode 100644 index 0000000000..386f1aae59 --- /dev/null +++ b/sw/airborne/peripherals/mcp355x.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* driver for MCP3550/1/3 + */ + +#include "peripherals/mcp355x.h" +#include "mcu_periph/spi.h" + +bool_t mcp355x_data_available; +int32_t mcp355x_data; +uint8_t mcp355x_spi_buf[4]; + +void mcp355x_init(void) { + mcp355x_data_available = FALSE; + mcp355x_data = 0; + + SpiClrCPOL(); + SpiClrCPHA(); +} + +void mcp355x_read(void) { + spi_buffer_length = 4; + spi_buffer_input = mcp355x_spi_buf; + SpiSelectSlave0(); + SpiStart(); +} + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif + +#include "mcu_periph/uart.h" +#include "messages.h" +#include "downlink.h" + +void mcp355x_event(void) { + static uint32_t filtered = 0; + if (spi_message_received) { + spi_message_received = FALSE; + if ((mcp355x_spi_buf[0]>>4) == 0) { + //mcp355x_data = (int32_t)(((uint32_t)mcp355x_spi_buf[0]<<16) | ((uint32_t)mcp355x_spi_buf[1]<<8) | (mcp355x_spi_buf[2])); + mcp355x_data = (int32_t)( + ((uint32_t)mcp355x_spi_buf[0]<<17) | + ((uint32_t)mcp355x_spi_buf[1]<<9) | + ((uint32_t)mcp355x_spi_buf[2]<<1) | + (mcp355x_spi_buf[3]>>7)); + filtered = (5*filtered + mcp355x_data) / (6); + DOWNLINK_SEND_DEBUG(DefaultChannel,4,mcp355x_spi_buf); + DOWNLINK_SEND_BARO_RAW(DefaultChannel,&mcp355x_data,&filtered); + } + } +} + diff --git a/sw/airborne/peripherals/mcp355x.h b/sw/airborne/peripherals/mcp355x.h new file mode 100644 index 0000000000..cbc94e021f --- /dev/null +++ b/sw/airborne/peripherals/mcp355x.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* driver for MPC3550/1/3 + */ + +#ifndef MCP355X_H +#define MCP355X_H + +#include "std.h" + +extern bool_t mcp355x_data_available; +extern int32_t mcp355x_data; + +extern void mcp355x_init(void); +extern void mcp355x_read(void); +extern void mcp355x_event(void); + +#endif + diff --git a/sw/airborne/subsystems/radio_control/rc_datalink.c b/sw/airborne/subsystems/radio_control/rc_datalink.c index 1d7a39ccb5..265ba528cd 100644 --- a/sw/airborne/subsystems/radio_control/rc_datalink.c +++ b/sw/airborne/subsystems/radio_control/rc_datalink.c @@ -44,6 +44,7 @@ void parse_rc_3ch_datalink( uint8_t throttle_mode, rc_dl_values[RADIO_PITCH] = pitch; rc_dl_values[RADIO_THROTTLE] = (int8_t)throttle; rc_dl_values[RADIO_MODE] = (int8_t)mode; + rc_dl_values[RADIO_YAW] = 0; rc_dl_frame_available = TRUE; } diff --git a/sw/airborne/subsystems/radio_control/rc_datalink.h b/sw/airborne/subsystems/radio_control/rc_datalink.h index ca72750480..acc03a218a 100644 --- a/sw/airborne/subsystems/radio_control/rc_datalink.h +++ b/sw/airborne/subsystems/radio_control/rc_datalink.h @@ -64,14 +64,14 @@ extern void parse_rc_4ch_datalink( /** * Macro that normalize rc_dl_values to radio values */ -#define NormalizeRcDl(_in, _out) { \ +#define NormalizeRcDl(_in, _out) { \ _out[RADIO_ROLL] = (MAX_PPRZ/128) * _in[RADIO_ROLL]; \ Bound(_out[RADIO_ROLL], MIN_PPRZ, MAX_PPRZ); \ _out[RADIO_PITCH] = (MAX_PPRZ/128) * _in[RADIO_PITCH]; \ Bound(_out[RADIO_PITCH], MIN_PPRZ, MAX_PPRZ); \ - _out[RADIO_YAW] = 0; \ + _out[RADIO_YAW] = (MAX_PPRZ/128) * _in[RADIO_YAW]; \ Bound(_out[RADIO_YAW], MIN_PPRZ, MAX_PPRZ); \ - _out[RADIO_THROTTLE] = ((MAX_PPRZ/128) * _in[RADIO_THROTTLE]); \ + _out[RADIO_THROTTLE] = ((MAX_PPRZ/128) * _in[RADIO_THROTTLE]); \ Bound(_out[RADIO_THROTTLE], 0, MAX_PPRZ); \ _out[RADIO_MODE] = MAX_PPRZ * (_in[RADIO_MODE] - 1); \ Bound(_out[RADIO_MODE], MIN_PPRZ, MAX_PPRZ); \ diff --git a/sw/ground_segment/cockpit/gcs.ml b/sw/ground_segment/cockpit/gcs.ml index e0b452f8f1..6f832fa8a0 100644 --- a/sw/ground_segment/cockpit/gcs.ml +++ b/sw/ground_segment/cockpit/gcs.ml @@ -359,6 +359,7 @@ let options = "-no_google_http", Arg.Unit (fun () -> Gm.set_policy Gm.NoHttp), "Switch off Google Maps downloading"; "-ortho", Arg.Set_string get_bdortho, "IGN tiles path"; "-osm", Arg.Unit (fun () -> Gm.set_maps_source Gm.OSM), "Use OpenStreetMap database (default is Google)"; + "-ms", Arg.Unit (fun () -> Gm.set_maps_source Gm.MS), "Use Microsoft maps database (default is Google)"; "-particules", Arg.Set display_particules, "Display particules"; "-plugin", Arg.Set_string plugin_window, "External X application (launched with the id of the plugin window as argument)"; "-ref", Arg.Set_string geo_ref, "Geographic ref (e.g. 'WGS84 43.605 1.443')"; @@ -404,10 +405,13 @@ let create_geomap = fun switch_fullscreen editor_frame -> let maps_source_menu = map_menu_fact#add_submenu "Maps Source" in let maps_source_fact = new GMenu.factory maps_source_menu in let group = ref None in + (* Determine a decent default selected item *) + let active_maps_source = Gm.get_maps_source () in List.iter (fun maps_source -> let callback = fun b -> if b then Gm.set_maps_source maps_source in - let menu_item = maps_source_fact#add_radio_item ~group: !group ~callback (Gm.string_of_maps_source maps_source) in + let active = (maps_source = active_maps_source) in + let menu_item = maps_source_fact#add_radio_item ~group: !group ~active ~callback (Gm.string_of_maps_source maps_source) in group := menu_item#group) Gm.maps_sources; diff --git a/sw/ground_segment/cockpit/live.ml b/sw/ground_segment/cockpit/live.ml index 03ac26bc1b..9018f8cb2a 100644 --- a/sw/ground_segment/cockpit/live.ml +++ b/sw/ground_segment/cockpit/live.ml @@ -549,7 +549,10 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id let settings_file = Http.file_of_url settings_url in let settings_xml = try - ExtXml.parse_file ~noprovedtd:true settings_file + if String.compare "replay" settings_file <> 0 then + ExtXml.parse_file ~noprovedtd:true settings_file + else + Xml.Element("empty", [], []) with exc -> prerr_endline (Printexc.to_string exc); Xml.Element("empty", [], []) diff --git a/sw/ground_segment/joystick/input2ivy.ml b/sw/ground_segment/joystick/input2ivy.ml index dbeafa377a..b493524587 100644 --- a/sw/ground_segment/joystick/input2ivy.ml +++ b/sw/ground_segment/joystick/input2ivy.ml @@ -88,7 +88,8 @@ type msg = { msg_class : string; fields : (string * Syntax.expression) list; on_event : Syntax.expression option; - send_always : bool + send_always : bool; + has_ac_id : bool } (** Representation of a variable *) @@ -230,12 +231,13 @@ let parse_msg = fun msg -> and msg_class = Xml.attrib msg "class" and send_always = (try (Xml.attrib msg "send_always") = "true" with _ -> false) in - let fields = + let fields, has_ac_id = match get_message_type msg_class with "Message" -> let msg_descr = get_message msg_class msg_name in - List.map (parse_msg_field msg_descr) (Xml.children msg) - | "Trim" -> [] + (List.map (parse_msg_field msg_descr) (Xml.children msg), + List.mem_assoc "ac_id" msg_descr.Pprz.fields) + | "Trim" -> ([], false) | _ -> failwith ("Unknown message class type") in let on_event = @@ -245,7 +247,8 @@ let parse_msg = fun msg -> msg_class = msg_class; fields = fields; on_event = on_event; - send_always = send_always + send_always = send_always; + has_ac_id = has_ac_id } (** Parse an XML list of variables and set function *) @@ -478,7 +481,7 @@ let execute_action = fun ac_id inputs buttons axis variables message -> let previous_values = get_previous_values message.msg_name in (* FIXME ((value <> previous) && on_event) || send_always ??? *) if ( ( (on_event, values) <> previous_values ) || message.send_always ) && on_event then begin - let vs = ("ac_id", Pprz.Int ac_id) :: values in + let vs = if message.has_ac_id then ("ac_id", Pprz.Int ac_id) :: values else values in match message.msg_class with "datalink" -> DL.message_send "input2ivy" message.msg_name vs | "ground" -> G.message_send "input2ivy" message.msg_name vs diff --git a/sw/ground_segment/misc/Makefile b/sw/ground_segment/misc/Makefile index d2c1539164..9e15b25a0f 100644 --- a/sw/ground_segment/misc/Makefile +++ b/sw/ground_segment/misc/Makefile @@ -2,12 +2,12 @@ UNAME = $(shell uname -s) ifeq ("$(UNAME)","Darwin") LIBRARYS = -L/opt/local/lib -else - LIBRARYS = -s +else + LIBRARYS = -s endif -all: davis2ivy kestrel2ivy ivy2serial +all: davis2ivy kestrel2ivy clean: rm *.o davis2ivy kestrel2ivy @@ -18,9 +18,5 @@ davis2ivy: davis2ivy.o kestrel2ivy: kestrel2ivy.o g++ -o kestrel2ivy kestrel2ivy.o $(LIBRARYS) -livy -ivy2serial: ivy2serial.o - g++ -o ivy2serial ivy2serial.o $(LIBRARYS) -livy - - %.o : %.c gcc -c -O2 -Wall -I /opt/local/include/ $< diff --git a/sw/ground_segment/misc/ivy2serial.c b/sw/ground_segment/misc/ivy2serial.c deleted file mode 100644 index 523dc58acb..0000000000 --- a/sw/ground_segment/misc/ivy2serial.c +++ /dev/null @@ -1,382 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -////////////////////////////////////////////////////////////////////////////////// -// SETTINGS -////////////////////////////////////////////////////////////////////////////////// - -// Serial Repeat Rate -long delay = 1000; - -////////////////////////////////////////////////////////////////////////////////// -// local_uav DATA -////////////////////////////////////////////////////////////////////////////////// - - -struct _uav_type_ -{ - // Header - unsigned char header; - - // Data - unsigned char ac_id; - short int phi, theta, psi, speed; - int utm_east,utm_north,utm_z; - unsigned char utm_zone; - unsigned char pprz_mode; - float desired_alt; - unsigned char block; - - // Footer - unsigned char footer; -} -__attribute__((packed)) - -local_uav, remote_uav; - -volatile unsigned char new_ivy_data = 0; -volatile unsigned char new_serial_data = 0; - -////////////////////////////////////////////////////////////////////////////////// -// IVY Reader -////////////////////////////////////////////////////////////////////////////////// - - -static void on_Attitude(IvyClientPtr app, void *user_data, int argc, char *argv[]) -{ -/* - - - - - -*/ - - local_uav.phi = (short int) (atof(argv[0]) * 1000.0); - local_uav.psi = (short int) (atof(argv[1]) * 1000.0); - local_uav.theta = (short int) (atof(argv[2]) * 1000.0); - - //printf("ATTITUDE ac=%d phi=%d theta=%d psi=%d ",local_uav.ac_id, local_uav.phi, local_uav.theta, local_uav.psi); -} - -static void on_Desired(IvyClientPtr app, void *user_data, int argc, char *argv[]) -{ -/* - - - - - - - - - -*/ - - local_uav.desired_alt = atof(argv[5]); -} - -static void on_Gps(IvyClientPtr app, void *user_data, int argc, char *argv[]) -{ -/* - - - - - - - - - - - - - -*/ - - local_uav.utm_east = atoi(argv[1]); - local_uav.utm_north = atoi(argv[2]); - local_uav.utm_z = atoi(argv[4]); - local_uav.utm_zone = atoi(argv[9]); - local_uav.speed = atoi(argv[5]); - - //printf("ATTITUDE ac=%d phi=%d theta=%d psi=%d ",local_uav.ac_id, local_uav.phi, local_uav.theta, local_uav.psi); - //printf("GPS ac=%d %d %d %d %d\n",local_uav.ac_id, local_uav.utm_east, local_uav.utm_north, local_uav.utm_z, local_uav.utm_zone); - - new_ivy_data = 1; -} - -////////////////////////////////////////////////////////////////////////////////// -// IVY Writer -////////////////////////////////////////////////////////////////////////////////// - -void send_ivy(void) -{ - float phi,theta,psi,z,zdot; - - if (new_serial_data == 0) - return; - - new_serial_data = 0; - - phi = ((float) remote_uav.phi) / 1000.0f; - theta = ((float) remote_uav.theta) / 1000.0f; - psi = ((float) remote_uav.psi) / 1000.0f; - - IvySendMsg("%d ALIVE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", remote_uav.ac_id); - - IvySendMsg("%d ATTITUDE %f %f %f\n", remote_uav.ac_id, phi, psi, theta); - -/* - remote_uav.utm_east = local_uav.utm_east; - remote_uav.utm_north = local_uav.utm_north + 5000; - remote_uav.utm_z = local_uav.utm_z + 1000; - remote_uav.utm_zone = local_uav.utm_zone; - remote_uav.speed = local_uav.speed * 4; - remote_uav.psi += 30.; -*/ - -/* - - - - - - - - - - - - - -*/ - - IvySendMsg("%d GPS 3 %d %d 0 %d %d 0 0 0 %d 0\n", remote_uav.ac_id, remote_uav.utm_east, remote_uav.utm_north, remote_uav.utm_z, remote_uav.speed, remote_uav.utm_zone); - -/* - - - - - - - -*/ - - IvySendMsg("%d FBW_STATUS 2 0 1 81 0 \n", remote_uav.ac_id); - - z = ((float)remote_uav.utm_z) / 1000.0f; - zdot = 0.0f; - IvySendMsg("%d ESTIMATOR %f %f \n", remote_uav.ac_id, z, zdot); - -/* - - - - - - - - - -*/ - IvySendMsg("%d DESIRED 0 0 0 0 0 %f 0 \n", remote_uav.ac_id, remote_uav.desired_alt); - - printf("IVY %d\n",remote_uav.ac_id); -} - -////////////////////////////////////////////////////////////////////////////////// -// SERIAL PORT -////////////////////////////////////////////////////////////////////////////////// - -// pointer -int fd; - -/// Open -void open_port(const char* device) { - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (fd == -1) { - fprintf(stderr, "open_port: unable to open device %s - ", device); - perror(NULL); - exit(EXIT_FAILURE); - } - // setup connection options - struct termios options; - - // get the current options - tcgetattr(fd, &options); - - // set local mode, enable receiver, set comm. options: - // 8 data bits, 1 stop bit, no parity, 9600 Baud - options.c_cflag = CLOCAL | CREAD | CS8 | B9600; - - // write options back to port - tcsetattr(fd, TCSANOW, &options); -} - -unsigned char* buf_tx = (unsigned char*) &local_uav; -unsigned char* buf_rx = (unsigned char*) &remote_uav; - -void send_port(void) -{ - int bytes; - int i = 0; - - if (new_ivy_data == 0) - return; - - new_ivy_data = 0; - - - local_uav.header = '@'; - local_uav.footer = 0; - // Checksum - for (i=0;i<(sizeof(local_uav)-1);i++) - { - local_uav.footer += buf_tx[i]; - printf("%x ", buf_tx[i]); - } - bytes = write(fd, &local_uav, sizeof(local_uav)); - printf("SENT: %d (%d bytes)\n",local_uav.ac_id, bytes); -} - -void read_port(void) -{ - int i; - static int counter = 0; - int readsize = sizeof(remote_uav) - counter; - int bytes = read(fd, buf_rx + counter, readsize); - unsigned char crc = 0; - - // printf("READ: %d bytes",bytes); - - if (bytes <= 0) - return; - - counter += bytes; - - if (counter >= sizeof(remote_uav)) - { - if (buf_rx[0] != '@') - { - printf("Protocol Error\n"); - } - for (i=0;i<(sizeof(remote_uav)-1);i++) - { - crc += buf_rx[i]; - printf("%x ", buf_rx[i]); - } - if (buf_rx[sizeof(remote_uav)-1] != crc) - { - printf("Checksum Error\n"); - } - printf("RECEIVED %d (%d bytes)\n",remote_uav.ac_id, counter); - counter -= sizeof(remote_uav); - - new_serial_data = 1; - remote_uav.ac_id = 6; - - send_ivy(); - } -} - -void close_port(void) -{ - close(fd); -} - -////////////////////////////////////////////////////////////////////////////////// -// TIMER -////////////////////////////////////////////////////////////////////////////////// - -// Timer -void handle_timer (TimerId id, void *data, unsigned long delta) -{ - static unsigned char dispatch = 0; - - // Every Time - read_port(); - - // One out of 2 - if (dispatch > 0) - { - send_port(); - dispatch = 0; - } - else - { - dispatch ++; - } -} - -TimerId tid; - -/// Handler for Ctrl-C, exits the main loop -void sigint_handler(int sig) { - printf("\nCLEAN STOP\n"); - IvyStop(); - TimerRemove(tid); - close_port(); -} - -////////////////////////////////////////////////////////////////////////////////// -// MAIN -////////////////////////////////////////////////////////////////////////////////// - -int main ( int argc, char** argv) -{ - int s = sizeof(local_uav); - - if (argc < 3) - { - printf("Use: ivy2serial ac_id serial_device\n"); - return -1; - } - - local_uav.ac_id = atoi(argv[1]); - - printf("Listening to AC=%d, \nSending Size of Data = %d \n",local_uav.ac_id, s); - - // make Ctrl-C stop the main loop and clean up properly - signal(SIGINT, sigint_handler); - - // Open Serial or Die - open_port(argv[2]); - - // Init UAV - remote_uav.ac_id = 6; - - remote_uav.phi = 1000; - remote_uav.theta = 200; - remote_uav.psi = -3140; - - - // create timer (Ivy) - tid = TimerRepeatAfter (0, delay / 2, handle_timer, 0); - - - IvyInit ("IVY <-> Serial", "IVY <-> Serial READY", NULL, NULL, NULL, NULL); - IvyBindMsg(on_Desired, NULL, "^%d DESIRED (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)",local_uav.ac_id); - IvyBindMsg(on_Attitude, NULL, "^%d ATTITUDE (\\S*) (\\S*) (\\S*)", local_uav.ac_id); - IvyBindMsg(on_Gps, NULL, "^%d GPS (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)",local_uav.ac_id); - IvyStart("127.255.255.255"); - - IvyMainLoop (); - - return 0; -} - diff --git a/sw/ground_segment/tmtc/Makefile b/sw/ground_segment/tmtc/Makefile index 72824e30df..93bb2bbe3f 100644 --- a/sw/ground_segment/tmtc/Makefile +++ b/sw/ground_segment/tmtc/Makefile @@ -35,7 +35,7 @@ include ../../../conf/Makefile.local CONF = ../../../conf VAR = ../../../var -all: link server messages settings dia diadec $(VAR)/boa.conf ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp +all: link server messages settings dia diadec $(VAR)/boa.conf ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge clean: rm -f link server messages settings dia diadec *.bak *~ core *.o .depend *.opt *.out *.cm* ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp @@ -151,6 +151,9 @@ c_ivy_client_example_2: c_ivy_client_example_2.c c_ivy_client_example_3: c_ivy_client_example_3.c $(CC) $(GTK_CFLAGS) -o $@ $< $(GTK_LDFLAGS) +ivy_serial_bridge: ivy_serial_bridge.c + $(CC) $(GTK_CFLAGS) -o $@ $< $(GTK_LDFLAGS) + # # Dependencies diff --git a/sw/ground_segment/tmtc/ivy_serial_bridge.c b/sw/ground_segment/tmtc/ivy_serial_bridge.c new file mode 100644 index 0000000000..5dade2b7fb --- /dev/null +++ b/sw/ground_segment/tmtc/ivy_serial_bridge.c @@ -0,0 +1,851 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +//#include + + +#define Dprintf(X, ... ) +//#define Dprintf printf + +////////////////////////////////////////////////////////////////////////////////// +// SETTINGS +////////////////////////////////////////////////////////////////////////////////// + +// Serial Repeat Rate +long delay = 1000; + + +GtkWidget *status_ivy; +GtkWidget *status_serial; +GtkWidget *status; + +char status_str[256]; +char status_ivy_str[256]; +char status_serial_str[256]; +char *port = ""; + +long int count_ivy = 0; +long int count_serial = 0; + +long int rx_bytes = 0; +long int tx_bytes = 0; +long int rx_error = 0; + +char modem_id[32] = ""; +int power_level = 4; + +////////////////////////////////////////////////////////////////////////////////// +// local_uav DATA +////////////////////////////////////////////////////////////////////////////////// + + +struct _uav_type_ +{ + // Header + unsigned char header; + + // Data + unsigned char ac_id; + short int phi, theta, psi, speed; + int utm_east,utm_north,utm_z; + unsigned char utm_zone; + unsigned char pprz_mode; + float desired_alt; + float climb; + unsigned char block; + + // Footer + unsigned char footer; +} +__attribute__((packed)) + +local_uav, remote_uav; + +volatile unsigned char new_ivy_data = 0; +volatile unsigned char new_serial_data = 0; + +////////////////////////////////////////////////////////////////////////////////// +// IVY Reader +////////////////////////////////////////////////////////////////////////////////// + + +static void on_Attitude(IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ +/* + + + + + +*/ + + local_uav.phi = (short int) (atof(argv[0]) * 1000.0); + local_uav.psi = (short int) (atof(argv[1]) * 1000.0); + local_uav.theta = (short int) (atof(argv[2]) * 1000.0); + + //Dprintf("ATTITUDE ac=%d phi=%d theta=%d psi=%d ",local_uav.ac_id, local_uav.phi, local_uav.theta, local_uav.psi); +} + +static void on_Estimator(IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ +/* + + + + +*/ + + local_uav.climb = atof(argv[1]); +} + +static void on_Navigation(IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ +/* + + + + + + + + + + +*/ + + local_uav.block = atoi(argv[0]); +} + +static void on_Desired(IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ +/* + + + + + + + + + +*/ + + local_uav.desired_alt = atof(argv[5]); +} + +static void on_Gps(IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ +/* + + + + + + + + + + + + + +*/ + + local_uav.utm_east = atoi(argv[1]); + local_uav.utm_north = atoi(argv[2]); + local_uav.utm_z = atoi(argv[4]); + local_uav.utm_zone = atoi(argv[9]); + local_uav.speed = atoi(argv[5]); + + //Dprintf("ATTITUDE ac=%d phi=%d theta=%d psi=%d ",local_uav.ac_id, local_uav.phi, local_uav.theta, local_uav.psi); + //Dprintf("GPS ac=%d %d %d %d %d\n",local_uav.ac_id, local_uav.utm_east, local_uav.utm_north, local_uav.utm_z, local_uav.utm_zone); + + new_ivy_data = 1; +} + +////////////////////////////////////////////////////////////////////////////////// +// IVY Writer +////////////////////////////////////////////////////////////////////////////////// + +void send_ivy(void) +{ + float phi,theta,psi,z,zdot; + + if (new_serial_data == 0) + return; + + new_serial_data = 0; + + phi = ((float) remote_uav.phi) / 1000.0f; + theta = ((float) remote_uav.theta) / 1000.0f; + psi = ((float) remote_uav.psi) / 1000.0f; + + IvySendMsg("%d ALIVE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", remote_uav.ac_id); + + IvySendMsg("%d ATTITUDE %f %f %f\n", remote_uav.ac_id, phi, psi, theta); + +/* + remote_uav.utm_east = local_uav.utm_east; + remote_uav.utm_north = local_uav.utm_north + 5000; + remote_uav.utm_z = local_uav.utm_z + 1000; + remote_uav.utm_zone = local_uav.utm_zone; + remote_uav.speed = local_uav.speed * 4; + remote_uav.psi += 30.; +*/ + +/* + + + + + + + + + + + + + +*/ + + IvySendMsg("%d GPS 3 %d %d 0 %d %d 0 0 0 %d 0\n", remote_uav.ac_id, remote_uav.utm_east, remote_uav.utm_north, remote_uav.utm_z, remote_uav.speed, remote_uav.utm_zone); + +/* + + + + + + + +*/ + + IvySendMsg("%d FBW_STATUS 2 0 1 81 0 \n", remote_uav.ac_id); + + z = ((float)remote_uav.utm_z) / 1000.0f; + zdot = remote_uav.climb; + IvySendMsg("%d ESTIMATOR %f %f \n", remote_uav.ac_id, z, zdot); + +/* + + + + + + + + + +*/ + IvySendMsg("%d DESIRED 0 0 0 0 0 %f 0 \n", remote_uav.ac_id, remote_uav.desired_alt); + +/* + + + + + + + + + + +*/ + + IvySendMsg("%d NAVIGATION %d 0 0 0 0 0 0 0 \n", remote_uav.ac_id, remote_uav.block); + +/* + + + + + + + + + + +*/ + + // IvySendMsg("%d BAT 0 81 0 %ld 0 0 0 0\n", remote_uav.ac_id, count_serial); + +/* + + + + + + + + +*/ + + // IvySendMsg("%d PPRZ_MODE 0 0 0 0 0 0\n", remote_uav.ac_id); + +/* // Needed to show any NAV info like current block number + + + + + +*/ + + static int delayer = 10; + delayer++; + if (delayer > 5) + { + IvySendMsg("%d NAVIGATION_REF %d %d %d\n", remote_uav.ac_id, remote_uav.utm_east, remote_uav.utm_north, remote_uav.utm_zone); + delayer = 0; + } + + + + + count_serial++; + + sprintf(status_serial_str, "Read %d from '%s': forwarding to IVY [%ld] {Rx=%ld} {Err=%ld}", remote_uav.ac_id, port, count_serial, rx_bytes, rx_error); + gtk_label_set_text( GTK_LABEL(status_serial), status_serial_str ); +} + +////////////////////////////////////////////////////////////////////////////////// +// SERIAL PORT +////////////////////////////////////////////////////////////////////////////////// + +// pointer +int fd = 0; + +/// Open +void open_port(const char* device) { + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd == -1) { + fprintf(stderr, "open_port: unable to open device %s - ", device); + perror(NULL); + exit(EXIT_FAILURE); + } + // setup connection options + struct termios options; + + // get the current options + tcgetattr(fd, &options); + + // set local mode, enable receiver, set comm. options: + // 8 data bits, 1 stop bit, no parity, 9600 Baud + options.c_cflag = CLOCAL | CREAD | CS8 | B9600; + + // write options back to port + tcsetattr(fd, TCSANOW, &options); +} + +unsigned char* buf_tx = (unsigned char*) &local_uav; +unsigned char* buf_rx = (unsigned char*) &remote_uav; + +void send_port(void) +{ + int bytes; + int i = 0; + + if (new_ivy_data == 0) + return; + + new_ivy_data = 0; + + + local_uav.header = '@'; + local_uav.footer = 0; + // Checksum + for (i=0;i<(sizeof(local_uav)-1);i++) + { + local_uav.footer += buf_tx[i]; + Dprintf("%x ", buf_tx[i]); + } + bytes = write(fd, &local_uav, sizeof(local_uav)); + + tx_bytes += bytes; + + Dprintf("SENT: %d (%d bytes)\n",local_uav.ac_id, bytes); + + count_ivy++; + + sprintf(status_ivy_str, "Received %d from IVY: forwarding to '%s' [%ld] {Tx=%ld}", local_uav.ac_id, port, count_ivy, tx_bytes); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); +} + +int set_power_level = -1; +int get_power_level = -1; + +int handle_api(void) +{ + static int step = 0; + int bytes; + int i=0; + char buff[32]; + + // ATPL4 = power level 4 + // ATMT0 = zero retry on broadcast + // ATRR = mac retry on NACK + + // ATDH = 0x00000000 + // ATDL = 0x0000FFFF + + // read only: + // Serial High + // Serial Low + + // ATDC = duty cycle status (percent 0 - 100) + // ATDB = Signal Strength + + + // ATWR = write to flash + // ATCN = exit command mode + + + step++; + + if (step > 35) + { + step = 35; + return 1; + } + + switch(step) + { + case 1: + sprintf(buff,"+++"); + bytes = write(fd, buff, strlen(buff)); + printf("+++ (bytes=%d %d)\n",bytes, fd); + + buff[strlen(buff)] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + + break; + case 8: + sprintf(buff,"ATPL\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATPL\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 10: + sprintf(buff,"ATPL%d\r", power_level); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATPL%d\n",power_level); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 12: + sprintf(buff,"ATPL\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATPL\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 14: + sprintf(buff,"ATDH\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATDH\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 16: + sprintf(buff,"ATDL\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATDL\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 18: + sprintf(buff,"ATSH\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATSH\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 20: + sprintf(buff,"ATSL\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATSL\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 22: + sprintf(buff,"ATMT0\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATMT0\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 24: + sprintf(buff,"ATRR0\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATRR0\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 26: + sprintf(buff,"ATDH00000000\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATDH00000000\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 28: + sprintf(buff,"ATDL0000FFFF\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATDL0000FFFF\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 30: + sprintf(buff,"ATWR\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATWR\n"); + + buff[strlen(buff) - 1] = 0; + strcpy(status_ivy_str,buff); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + break; + case 32: + sprintf(buff,"ATCN\r"); + write(fd, (unsigned char*) buff, strlen(buff)); + printf("ATCN\n"); + printf("Quit API\n"); + modem_id[16]=0; + sprintf(buff, ", XB_ADDR='%s', ", modem_id); + strcat(status_str,buff); + sprintf(buff, "ATPL=%d", power_level); + strcat(status_str,buff); + gtk_label_set_text( GTK_LABEL(status), status_str ); + break; + case 34: + sprintf(status_ivy_str, "---"); + gtk_label_set_text( GTK_LABEL(status_ivy), status_ivy_str ); + sprintf(status_serial_str, "---"); + gtk_label_set_text( GTK_LABEL(status_serial), status_serial_str ); + + break; + case 7: + case 9: + case 11: + case 13: + case 15: + case 17: + case 19: + case 21: + case 23: + case 25: + case 27: + case 29: + case 31: + case 33: + bytes = read(fd, (unsigned char*) buff, 32); + printf("Bytes %d %d\n",bytes, fd); + if ((bytes > 1) && (bytes < 10)) + { + buff[bytes-1] = 0; + strcpy(status_serial_str, buff); + gtk_label_set_text( GTK_LABEL(status_serial), status_serial_str ); + } + for (i=0;i= sizeof(remote_uav)) + { + if (buf_rx[0] != '@') + { + int head = 0; + for (head=0; head= 0) && (handle_api() == 0)) + return TRUE; + + // Every Time + read_port(); + + // One out of 4 + if (dispatch > 2) + { + send_port(); + dispatch = 0; + } + else + { + dispatch ++; + } + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////////// +// MAIN +////////////////////////////////////////////////////////////////////////////////// + +gint delete_event( GtkWidget *widget, + GdkEvent *event, + gpointer data ) +{ + g_print ("CLEAN STOP\n"); + + close_port(); + IvyStop(); + + exit(0); + + return(FALSE); // false = delete window, FALSE = keep active +} + + +int main ( int argc, char** argv) +{ + int s = sizeof(local_uav); + + gtk_init(&argc, &argv); + + if (argc < 3) + { + printf("Use: ivy2serial ac_id serial_device\n"); + printf("or\n"); + printf("Use: ivy2serial ac_id serial_device xbee_power_level [0-4] to configure the xbee as broadcast, no retries\n"); + return -1; + } + + if (argc == 4) + { + printf("Programming XBee Modem\n"); + power_level = (int) (argv[3][0]) - (int) '0'; + if (power_level < 0) + power_level = 0; + else if (power_level > 4) + power_level = 4; + printf("Set Power Level To: '%d'\n", power_level); + } + else + { + power_level = -1; + } + + local_uav.ac_id = atoi(argv[1]); + + sprintf(status_str, "Listening to AC=%d, Serial Data Size = %d",local_uav.ac_id, s); + sprintf(status_ivy_str, "---"); + sprintf(status_serial_str, "---"); + printf("%s\n",status_str); + + // Open Serial or Die + port = argv[2]; + open_port(port); + + // Init UAV + remote_uav.ac_id = 6; + + remote_uav.phi = 1000; + remote_uav.theta = 200; + remote_uav.psi = -3140; + + // Start IVY + IvyInit ("IVY <-> Serial", "IVY <-> Serial READY", NULL, NULL, NULL, NULL); + IvyBindMsg(on_Desired, NULL, "^%d DESIRED (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)",local_uav.ac_id); + IvyBindMsg(on_Estimator, NULL, "^%d ESTIMATOR (\\S*) (\\S*)",local_uav.ac_id); + IvyBindMsg(on_Navigation, NULL, "^%d NAVIGATION (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)",local_uav.ac_id); + IvyBindMsg(on_Attitude, NULL, "^%d ATTITUDE (\\S*) (\\S*) (\\S*)", local_uav.ac_id); + IvyBindMsg(on_Gps, NULL, "^%d GPS (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)",local_uav.ac_id); + IvyStart("127.255.255.255"); + + // Add Timer + gtk_timeout_add(delay / 4, timeout_callback, NULL); + + // GTK Window + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "IVY_Serial_Bridge"); + + gtk_signal_connect (GTK_OBJECT (window), "delete_event", + GTK_SIGNAL_FUNC (delete_event), NULL); + + GtkWidget *box = gtk_vbox_new(TRUE, 1); + gtk_container_add (GTK_CONTAINER (window), box); + + GtkWidget *hbox = gtk_hbox_new(FALSE, 1); + gtk_container_add (GTK_CONTAINER (box), hbox); + status = gtk_label_new( "Status:" ); + gtk_box_pack_start(GTK_BOX(hbox), status, FALSE, FALSE, 1); + gtk_label_set_justify( (GtkLabel*) status, GTK_JUSTIFY_LEFT ); + status = gtk_label_new( status_str ); + gtk_box_pack_start(GTK_BOX(hbox), status, FALSE, FALSE, 1); + gtk_label_set_justify( (GtkLabel*) status, GTK_JUSTIFY_LEFT ); + + hbox = gtk_hbox_new(FALSE, 1); + gtk_container_add (GTK_CONTAINER (box), hbox); + status_ivy = gtk_label_new( "IVY->SERIAL:" ); + gtk_box_pack_start(GTK_BOX(hbox), status_ivy, FALSE, FALSE, 1); + gtk_label_set_justify( (GtkLabel*) status_ivy, GTK_JUSTIFY_LEFT ); + status_ivy = gtk_label_new( status_ivy_str ); + gtk_box_pack_start(GTK_BOX(hbox), status_ivy, FALSE, FALSE, 1); + gtk_label_set_justify( (GtkLabel*) status_ivy, GTK_JUSTIFY_LEFT ); + + hbox = gtk_hbox_new(FALSE, 1); + gtk_container_add (GTK_CONTAINER (box), hbox); + status_serial = gtk_label_new( "SERIAL->IVY:" ); + gtk_box_pack_start(GTK_BOX(hbox), status_serial, FALSE, FALSE, 1); + gtk_label_set_justify( (GtkLabel*) status_serial, GTK_JUSTIFY_LEFT ); + status_serial = gtk_label_new( status_serial_str ); + gtk_label_set_justify( GTK_LABEL(status_serial), GTK_JUSTIFY_LEFT ); + gtk_box_pack_start(GTK_BOX(hbox), status_serial, FALSE, FALSE, 1); + + + gtk_widget_show_all(window); + + gtk_main(); + + // Clean up + fprintf(stderr,"Stopping\n"); + + + return 0; +} + diff --git a/sw/ground_segment/tmtc/server.ml b/sw/ground_segment/tmtc/server.ml index 82964a1be8..34cc714840 100644 --- a/sw/ground_segment/tmtc/server.ml +++ b/sw/ground_segment/tmtc/server.ml @@ -599,7 +599,8 @@ let send_config = fun http _asker args -> let fp = prefix ("var" // ac_name // "flight_plan.xml") and af = prefix ("conf" // ExtXml.attrib conf "airframe") and rc = prefix ("conf" // ExtXml.attrib conf "radio") - and settings = prefix ("var" // ac_name // "settings.xml") in + and settings = if not _is_replayed then prefix ("var" // ac_name // + "settings.xml") else "file://replay" in let col = try Xml.attrib conf "gui_color" with _ -> new_color () in let ac_name = try Xml.attrib conf "name" with _ -> "" in [ "ac_id", Pprz.String ac_id; diff --git a/sw/lib/ocaml/gm.ml b/sw/lib/ocaml/gm.ml index 327644d264..82a564f694 100644 --- a/sw/lib/ocaml/gm.ml +++ b/sw/lib/ocaml/gm.ml @@ -48,6 +48,7 @@ let string_of_maps_source = function let maps_source = ref Google let set_maps_source = fun s -> maps_source := s +let get_maps_source = fun () -> !maps_source let mkdir = fun d -> if not (Sys.file_exists d) then diff --git a/sw/lib/ocaml/gm.mli b/sw/lib/ocaml/gm.mli index 855fff5f96..66e2ef284b 100644 --- a/sw/lib/ocaml/gm.mli +++ b/sw/lib/ocaml/gm.mli @@ -38,6 +38,9 @@ type tile_t = { type maps_source = Google | OSM | MS val string_of_maps_source : maps_source -> string val maps_sources : maps_source list +val set_maps_source : maps_source -> unit +val get_maps_source : unit -> maps_source +(** Initialized to Google *) val tile_of_geo : Latlong.geographic -> int -> tile_t (** [tile_string geo zoom] Returns the tile description containing a @@ -56,9 +59,6 @@ val set_policy : policy -> unit val get_policy : unit -> policy (** Initialized to CacheOrHttp using cache and http access *) -val set_maps_source : maps_source -> unit -(** Initialized to Google *) - exception Not_available val get_image : string -> tile_t * string