diff --git a/conf/airframes/ENAC/conf_enac.xml b/conf/airframes/ENAC/conf_enac.xml index 5e69b098e0..149d98a161 100644 --- a/conf/airframes/ENAC/conf_enac.xml +++ b/conf/airframes/ENAC/conf_enac.xml @@ -7,7 +7,7 @@ telemetry="telemetry/fixedwing_flight_recorder.xml" flight_plan="flight_plans/basic.xml" settings="settings/fixedwing_basic.xml" - settings_modules="modules/ahrs_float_dcm.xml modules/gps.xml modules/guidance_basic_fw.xml modules/imu_common.xml modules/nav_basic_fw.xml modules/stabilization_attitude_fw.xml" + settings_modules="modules/ahrs_float_dcm.xml modules/gps.xml modules/guidance_basic_fw.xml modules/imu_common.xml modules/nav_basic_fw.xml modules/power_switch.xml modules/stabilization_attitude_fw.xml" gui_color="blue" /> - i2c,baro_board_common + i2c,baro_board_common,power_switch baro diff --git a/conf/modules/boards/apogee_1.0_chibios.xml b/conf/modules/boards/apogee_1.0_chibios.xml index 330e675fdd..8d952704e5 100644 --- a/conf/modules/boards/apogee_1.0_chibios.xml +++ b/conf/modules/boards/apogee_1.0_chibios.xml @@ -7,7 +7,7 @@ - i2c,baro_board_common,hard_fault_recovery + i2c,baro_board_common,hard_fault_recovery,power_switch baro diff --git a/conf/modules/boards/cube_orange.xml b/conf/modules/boards/cube_orange.xml index 8489231c2a..d9c9171c3d 100644 --- a/conf/modules/boards/cube_orange.xml +++ b/conf/modules/boards/cube_orange.xml @@ -10,6 +10,7 @@ spi_master,baro_ms5611_spi + diff --git a/conf/modules/boards/px4fmu_5.0_chibios.xml b/conf/modules/boards/px4fmu_5.0_chibios.xml index aae15232d8..43de3466d7 100644 --- a/conf/modules/boards/px4fmu_5.0_chibios.xml +++ b/conf/modules/boards/px4fmu_5.0_chibios.xml @@ -10,6 +10,7 @@ spi_master,baro_board + diff --git a/conf/modules/power_switch.xml b/conf/modules/power_switch.xml new file mode 100644 index 0000000000..a35cae22bc --- /dev/null +++ b/conf/modules/power_switch.xml @@ -0,0 +1,22 @@ + + + + + Simple power switch module to set a specific GPIO pin + + + + + + + + +
+ +
+ + + + +
+ diff --git a/conf/settings/fixedwing_basic.xml b/conf/settings/fixedwing_basic.xml index 821e70ac58..ba98769357 100644 --- a/conf/settings/fixedwing_basic.xml +++ b/conf/settings/fixedwing_basic.xml @@ -23,5 +23,9 @@ + + + + diff --git a/conf/settings/power_switch.xml b/conf/settings/power_switch.xml deleted file mode 100644 index 60b34f163d..0000000000 --- a/conf/settings/power_switch.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/conf/settings/rotorcraft_basic.xml b/conf/settings/rotorcraft_basic.xml index f44268c68c..9149a68da9 100644 --- a/conf/settings/rotorcraft_basic.xml +++ b/conf/settings/rotorcraft_basic.xml @@ -6,11 +6,8 @@ - - - - + diff --git a/conf/settings/rotorcraft_basic_multi.xml b/conf/settings/rotorcraft_basic_multi.xml deleted file mode 100644 index 19ee8acd95..0000000000 --- a/conf/settings/rotorcraft_basic_multi.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/settings/rover_basic.xml b/conf/settings/rover_basic.xml index b1756c8351..9e0209824a 100644 --- a/conf/settings/rover_basic.xml +++ b/conf/settings/rover_basic.xml @@ -5,11 +5,8 @@ - - - - + diff --git a/conf/settings/switchlight.xml b/conf/settings/switchlight.xml deleted file mode 100644 index 98cfc57617..0000000000 --- a/conf/settings/switchlight.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/sw/airborne/arch/chibios/board.c b/sw/airborne/arch/chibios/board.c index b2350b7eb7..2de0a391a8 100644 --- a/sw/airborne/arch/chibios/board.c +++ b/sw/airborne/arch/chibios/board.c @@ -289,7 +289,6 @@ bool sdc_lld_is_write_protected(SDCDriver *sdcp) */ bool mmc_lld_is_card_inserted(MMCDriver *mmcp) { - (void)mmcp; /* TODO: Fill the implementation.*/ return true; @@ -300,7 +299,6 @@ bool mmc_lld_is_card_inserted(MMCDriver *mmcp) */ bool mmc_lld_is_write_protected(MMCDriver *mmcp) { - (void)mmcp; /* TODO: Fill the implementation.*/ return false; diff --git a/sw/airborne/arch/chibios/mcu_arch.c b/sw/airborne/arch/chibios/mcu_arch.c index 7a6395de23..facfbecee4 100644 --- a/sw/airborne/arch/chibios/mcu_arch.c +++ b/sw/airborne/arch/chibios/mcu_arch.c @@ -57,31 +57,31 @@ IN_BCKP_SECTION(volatile bool hard_fault); CH_IRQ_HANDLER(HardFault_Handler) { hard_fault = true; - NVIC_SystemReset(); + mcu_reboot(MCU_REBOOT_FAST); } CH_IRQ_HANDLER(NMI_Handler) { hard_fault = true; - NVIC_SystemReset(); + mcu_reboot(MCU_REBOOT_FAST); } CH_IRQ_HANDLER(MemManage_Handler) { hard_fault = true; - NVIC_SystemReset(); + mcu_reboot(MCU_REBOOT_FAST); } CH_IRQ_HANDLER(BusFault_Handler) { hard_fault = true; - NVIC_SystemReset(); + mcu_reboot(MCU_REBOOT_FAST); } CH_IRQ_HANDLER(UsageFault_Handler) { hard_fault = true; - NVIC_SystemReset(); + mcu_reboot(MCU_REBOOT_FAST); } bool recovering_from_hard_fault; @@ -99,12 +99,27 @@ bool recovering_from_hard_fault; #error Hard fault recovery not supported #endif +#endif /* USE_HARD_FAULT_RECOVERY */ + +/** + * @brief RTC backup register values + */ +enum rtc_boot_magic { + RTC_BOOT_OFF = 0, ///< Normal boot + RTC_BOOT_HOLD = 0xb0070001, ///< Hold in bootloader, do not boot application + RTC_BOOT_FAST = 0xb0070002, ///< No timeout in bootloader + RTC_BOOT_CANBL = 0xb0080000, ///< CAN bootloader, ORd with 8 bit local node ID + RTC_BOOT_FWOK = 0xb0093a26 ///< indicates FW ran for 30s +}; + +/* Local functions */ +static void mcu_deep_sleep(void); +#if defined(USE_RTC_BACKUP) +static void mcu_set_rtcbackup(uint32_t val); #endif - -/* - * SCB_VTOR has to be relocated if Luftboot is used - * The new SCB_VTOR location is defined in the board makefile +/** + * @brief Initialize the specific archittecture functions */ void mcu_arch_init(void) { @@ -143,14 +158,41 @@ void mcu_arch_init(void) RCC->CSR = RCC_CSR_RMVF; // end of reset bit probing #endif /* USE_HARD_FAULT_RECOVERY */ +} +/** + * @brief Reboot the MCU + * - POWEROFF will go the deep sleep + * - NORMAL will do a normal reboot (also to bootloader) + * - FAST will try to skip the bootloader + * - BOOTLOADER will try to keep the MCU in bootloader + * @param reboot_state The sate to reboot to + */ +void mcu_reboot(enum reboot_state_t reboot_state) +{ + // Powering off/deep sleep instead + if(reboot_state == MCU_REBOOT_POWEROFF) { + mcu_deep_sleep(); + return; + } + +#if defined(USE_RTC_BACKUP) + // Set the RTC backup register if possible + if(reboot_state == MCU_REBOOT_FAST) + mcu_set_rtcbackup(RTC_BOOT_FAST); + else if(reboot_state == MCU_REBOOT_BOOTLOADER) + mcu_set_rtcbackup(RTC_BOOT_HOLD); +#endif + + // Restart the MCU + NVIC_SystemReset(); } /** * @brief Save energy for performing operations on shutdown * Used for example to shutdown SD-card logging */ -void mcu_periph_energy_save(void) +void mcu_energy_save(void) { #if defined(ENERGY_SAVE_INPUTS) BOARD_GROUP_DECLFOREACH(input_line, ENERGY_SAVE_INPUTS) { @@ -164,3 +206,75 @@ void mcu_periph_energy_save(void) #endif } +/** Put MCU into deep sleep mode + * + * This can be used when closing the SD log files + * right after a power down to save the remaining + * energy for the SD card internal MCU + * + * Never call this during flight! + */ +static void mcu_deep_sleep(void) +{ +#if defined(STM32F4XX) + /* clear PDDS and LPDS bits */ + PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS); + /* set LPDS and clear */ + PWR->CR |= (PWR_CR_LPDS | PWR_CR_CSBF | PWR_CR_CWUF); +#elif defined(STM32F7XX) + /* clear PDDS and LPDS bits */ + PWR->CR1 &= ~(PWR_CR1_PDDS | PWR_CR1_LPDS); + /* set LPDS and clear */ + PWR->CR1 |= (PWR_CR1_LPDS | PWR_CR1_CSBF); +#elif defined(STM32H7XX) + /* clear LPDS */ + PWR->CR1 &= ~PWR_CR1_LPDS; + /* set LPDS */ + PWR->CR1 |= PWR_CR1_LPDS; +#endif + + /* Setup the deepsleep mask */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + __disable_irq(); + + __SEV(); + __WFE(); + __WFE(); + + __enable_irq(); + + /* clear the deepsleep mask */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; +} + +#if defined(USE_RTC_BACKUP) +/** + * @brief Set the RTC backup register + * This sets the first register in the RTC backup register, used for bootloader + * @param val The value to set in the register + */ +static void mcu_set_rtcbackup(uint32_t val) { +#if !defined(STM32F1) + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + RCC->BDCR |= STM32_RTCSEL; + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#ifdef PWR_CR_DBP + PWR->CR |= PWR_CR_DBP; +#else + PWR->CR1 |= PWR_CR1_DBP; +#endif +#endif + +#if defined(STM32F1) + volatile uint32_t *dr = (volatile uint32_t *)&BKP->DR1; + dr[0] = (val) & 0xFFFF; + dr[1] = (val) >> 16; +#elif defined(STM32G4) + ((volatile uint32_t *)&TAMP->BKP0R)[0] = val; +#else + ((volatile uint32_t *)&RTC->BKP0R)[0] = val; +#endif +} +#endif /* USE_RTC_BACKUP */ diff --git a/sw/airborne/arch/chibios/mcu_arch.h b/sw/airborne/arch/chibios/mcu_arch.h index b71ae408cd..b34bb3e9b3 100644 --- a/sw/airborne/arch/chibios/mcu_arch.h +++ b/sw/airborne/arch/chibios/mcu_arch.h @@ -39,60 +39,4 @@ extern void mcu_arch_init(void); extern bool recovering_from_hard_fault; #endif -#include - -/** Put MCU into deep sleep mode - * - * This can be used when closing the SD log files - * right after a power down to save the remaining - * energy for the SD card internal MCU - * - * Never call this during flight! - */ -static inline void mcu_deep_sleep(void) -{ -#if defined(STM32F4XX) - /* clear PDDS and LPDS bits */ - PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS); - /* set LPDS and clear */ - PWR->CR |= (PWR_CR_LPDS | PWR_CR_CSBF | PWR_CR_CWUF); -#elif defined(STM32F7XX) - /* clear PDDS and LPDS bits */ - PWR->CR1 &= ~(PWR_CR1_PDDS | PWR_CR1_LPDS); - /* set LPDS and clear */ - PWR->CR1 |= (PWR_CR1_LPDS | PWR_CR1_CSBF); -#elif defined(STM32H7XX) - /* clear LPDS */ - PWR->CR1 &= ~PWR_CR1_LPDS; - /* set LPDS */ - PWR->CR1 |= PWR_CR1_LPDS; -#endif - - /* Setup the deepsleep mask */ - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - - __disable_irq(); - - __SEV(); - __WFE(); - __WFE(); - - __enable_irq(); - - /* clear the deepsleep mask */ - SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; -} - -/** Request a software reset of the MCU - */ -static inline void mcu_reset(void) -{ - NVIC_SystemReset(); -} - -/** Call board specific energy saving - * Can be necessary for closing on power off - */ -extern void mcu_periph_energy_save(void); - #endif /* CHIBIOS_MCU_ARCH_H */ diff --git a/sw/airborne/autopilot.c b/sw/airborne/autopilot.c index e306a5cb86..9e6d1df30c 100644 --- a/sw/airborne/autopilot.c +++ b/sw/airborne/autopilot.c @@ -116,15 +116,6 @@ void autopilot_init(void) autopilot.ground_detected = false; autopilot.detect_ground_once = false; autopilot.use_rc = true; - autopilot.power_switch = false; -#ifdef POWER_SWITCH_GPIO - gpio_setup_output(POWER_SWITCH_GPIO); -#ifdef POWER_SWITCH_ENABLE - autopilot_set_power_switch(POWER_SWITCH_ENABLE); // set initial status -#else - gpio_clear(POWER_SWITCH_GPIO); // by default POWER OFF -#endif -#endif // call firmware specific init autopilot_firmware_init(); @@ -300,20 +291,6 @@ bool autopilot_in_flight(void) return autopilot.in_flight; } -/** set power switch - */ -void autopilot_set_power_switch(bool power_switch) -{ -#ifdef POWER_SWITCH_GPIO - if (power_switch) { - gpio_set(POWER_SWITCH_GPIO); - } else { - gpio_clear(POWER_SWITCH_GPIO); - } -#endif - autopilot.power_switch = power_switch; -} - /** store settings */ void autopilot_store_settings(void) diff --git a/sw/airborne/autopilot.h b/sw/airborne/autopilot.h index eeed6cc875..67d468774b 100644 --- a/sw/airborne/autopilot.h +++ b/sw/airborne/autopilot.h @@ -70,7 +70,6 @@ struct pprz_autopilot { bool in_flight; ///< in flight status bool launch; ///< request launch bool use_rc; ///< enable/disable RC input - bool power_switch; ///< enable/disable power from power switch (if any) bool ground_detected; ///< automatic detection of landing bool detect_ground_once; ///< enable automatic detection of ground (one shot) }; @@ -173,15 +172,6 @@ extern bool autopilot_in_flight(void); */ extern void autopilot_reset_in_flight_counter(void); -/** Set power switch state - * This will actually enable the switch if POWER_SWITCH_GPIO is defined - * Also provide macro for dl_setting backward compatibility - * - * @param[in] power_switch true to enable, false to disable - */ -extern void autopilot_set_power_switch(bool power_switch); -#define autopilot_SetPowerSwitch(_ps) autopilot_set_power_switch(_ps) - /** Store marked settings in flash * Try to make sure that we don't write to flash while flying * Also provide macro for dl_setting backward compatibility diff --git a/sw/airborne/mcu.c b/sw/airborne/mcu.c index ebd9b9db28..ed25973034 100644 --- a/sw/airborne/mcu.c +++ b/sw/airborne/mcu.c @@ -84,6 +84,16 @@ void WEAK board_init2(void) /* default board init function does nothing... */ } +void WEAK mcu_reboot(enum reboot_state_t reboot_state __attribute__((unused))) +{ + /* default reboot function does nothing... */ +} + +void WEAK mcu_energy_save(void) +{ + /* default power saving function does nothing... */ +} + void mcu_init(void) { /* If we have a board specific init function, call it. diff --git a/sw/airborne/mcu.h b/sw/airborne/mcu.h index b16090db54..8e997c9536 100644 --- a/sw/airborne/mcu.h +++ b/sw/airborne/mcu.h @@ -36,6 +36,16 @@ * @{ */ +/** + * The requested reboot states + */ +enum reboot_state_t { + MCU_REBOOT_NORMAL, ///< Normal reboot + MCU_REBOOT_POWEROFF, ///< Poweroff the device + MCU_REBOOT_FAST, ///< Fast reboot (skip bootloader) + MCU_REBOOT_BOOTLOADER ///< Go to bootloader +}; + /** * Microcontroller peripherals initialization. * This function is responisble for setting up the microcontroller @@ -49,6 +59,20 @@ extern void mcu_init(void); */ extern void mcu_event(void); +/** + * Reboot the MCU + * Should not be called during flight or ciritcal operations + * @param state The state to reboot towards + */ +extern void mcu_reboot(enum reboot_state_t reboot_state); + +/** + * Puts the MCU in energy save mode + * This disables features of the MCU to save energy. This is used for + * example to quickly write to the SD card while powering off. + */ +extern void mcu_energy_save(void); + /** * Optional board init function called at the start of mcu_init(). */ diff --git a/sw/airborne/modules/boards/power_switch.c b/sw/airborne/modules/boards/power_switch.c new file mode 100644 index 0000000000..50290611b8 --- /dev/null +++ b/sw/airborne/modules/boards/power_switch.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) Freek van Tienen + * + * This file is part of paparazzi + * + * paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, see + * . + */ + +/** + * @file "modules/boards/power_switch.c" + * @author F. van Tienen + * Simple GPIO power switch module + */ +#include "power_switch.h" +#include "mcu_periph/gpio.h" +#include "generated/airframe.h" +bool power_switch_status = false; + +#if !defined(POWER_SWITCH_GPIO) +#error "The power switch module needs POWER_SWITCH_GPIO to be defined" +#endif + +/** + * @brief Intialize the power switch pins + * This sets the power switch pins to te initial state + */ +void power_switch_init(void) { + gpio_setup_output(POWER_SWITCH_GPIO); +#ifdef POWER_SWITCH_ENABLE + power_switch_set(POWER_SWITCH_ENABLE); +#else + gpio_clear(POWER_SWITCH_GPIO); +#endif +} + +/** + * @brief Set the power switch to enable/disable + * + * @param val True enables the pin, False disables the pin + */ +void power_switch_set(bool val) { + if(val) { + gpio_set(POWER_SWITCH_GPIO); + } else { + gpio_clear(POWER_SWITCH_GPIO); + } + + power_switch_status = val; +} diff --git a/sw/airborne/modules/boards/power_switch.h b/sw/airborne/modules/boards/power_switch.h new file mode 100644 index 0000000000..10d6ecbf8e --- /dev/null +++ b/sw/airborne/modules/boards/power_switch.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) Freek van Tienen + * + * This file is part of paparazzi + * + * paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, see + * . + */ + +/** + * @file "modules/boards/power_switch.h" + * @author F. van Tienen + * Simple GPIO power switch module + */ +#include "std.h" + +extern bool power_switch_status; +extern void power_switch_init(void); +extern void power_switch_set(bool val); diff --git a/sw/airborne/modules/loggers/sdlog_chibios.c b/sw/airborne/modules/loggers/sdlog_chibios.c index 3f83d814d6..1377a43ede 100644 --- a/sw/airborne/modules/loggers/sdlog_chibios.c +++ b/sw/airborne/modules/loggers/sdlog_chibios.c @@ -198,7 +198,7 @@ void sdlog_chibios_finish(const bool flush) if (pprzLogFile != -1) { // disable all required periph to save energy and maximize chance to flush files // to mass storage and avoid infamous dirty bit on filesystem - mcu_periph_energy_save(); + mcu_energy_save(); // if a FF_FS_REENTRANT is true, we can umount fs without closing // file, fatfs lock will assure that umount is done after a write, @@ -327,7 +327,7 @@ static void thd_bat_survey(void *arg) // Only put to deep sleep in case there is no power on the USB if (palReadPad(SDLOG_USB_VBUS_PORT, SDLOG_USB_VBUS_PIN) == PAL_LOW) { - mcu_deep_sleep(); + mcu_reboot(MCU_REBOOT_POWEROFF); } chThdSleep(TIME_INFINITE); while (true); // never goes here, only to avoid compiler warning: 'noreturn' function does return diff --git a/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c b/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c index 8b3493bb09..57bfca53b7 100644 --- a/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c +++ b/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c @@ -157,7 +157,7 @@ static void thdUsbStorage(void *arg) chThdSleepMilliseconds(500); - mcu_reset(); + mcu_reboot(MCU_REBOOT_FAST); } bool usbStorageIsItRunning(void) diff --git a/sw/tools/generators/gen_settings.ml b/sw/tools/generators/gen_settings.ml index b6c437ebf1..a1f3e0ee26 100644 --- a/sw/tools/generators/gen_settings.ml +++ b/sw/tools/generators/gen_settings.ml @@ -90,13 +90,16 @@ let print_dl_settings = fun out settings settings_xml -> try let h = ExtXml.attrib s "handler" in begin + let t = ExtXml.attrib_or_default s "type" "" in let m1 = ExtXml.attrib_or_default s "module" "" in let m2 = ExtXml.attrib_or_default s "header" "" in - match m1, m2 with - | "", "" -> prerr_endline (sprintf "Error: You need to specify the header (or module for legacy) attribute for setting %s to use the handler %s" v h); exit 1 - | "", _ -> lprintf out "case %d: %s_%s( _value ); _value = %s; break;\\\n" !idx (Filename.basename m2) h v - | _, "" -> lprintf out "case %d: %s_%s( _value ); _value = %s; break;\\\n" !idx (Filename.basename m1) h v - | _, _ -> prerr_endline (sprintf "Error: You can't specify both module and header attributes for setting %s to use the handler %s" v h); exit 1 + match m1, m2, t with + | "", "", _ -> prerr_endline (sprintf "Error: You need to specify the header (or module for legacy) attribute for setting %s to use the handler %s" v h); exit 1 + | "", _, "fun" -> lprintf out "case %d: %s_%s( _value ); break;\\\n" !idx (Filename.basename m2) h + | _, "", "fun" -> lprintf out "case %d: %s_%s( _value ); break;\\\n" !idx (Filename.basename m1) h + | "", _, _ -> lprintf out "case %d: %s_%s( _value ); _value = %s; break;\\\n" !idx (Filename.basename m2) h v + | _, "", _ -> lprintf out "case %d: %s_%s( _value ); _value = %s; break;\\\n" !idx (Filename.basename m1) h v + | _, _, _ -> prerr_endline (sprintf "Error: You can't specify both module and header attributes for setting %s to use the handler %s" v h); exit 1 end; with ExtXml.Error e -> lprintf out "case %d: %s = _value; break;\\\n" !idx v @@ -123,8 +126,12 @@ let print_dl_settings = fun out settings settings_xml -> right (); List.iter (fun s -> + let t = ExtXml.attrib_or_default s "type" "" in let v = ExtXml.attrib s "var" in - lprintf out "case %d: var = %s; break;\\\n" !idx v; incr idx) + match t with + | "fun" -> lprintf out "case %d: var = 0; break;\\\n" !idx; incr idx + | _ -> lprintf out "case %d: var = %s; break;\\\n" !idx v; incr idx + ) settings_xml; lprintf out "default: var = 0.; break;\\\n"; left (); @@ -143,8 +150,12 @@ let print_dl_settings = fun out settings settings_xml -> right (); List.iter (fun s -> + let t = ExtXml.attrib_or_default s "type" "" in let v = ExtXml.attrib s "var" in - lprintf out "case %d: return %s;\n" !idx v; incr idx) + match t with + | "fun" -> lprintf out "case %d: return 0;\n" !idx; incr idx + | _ -> lprintf out "case %d: return %s;\n" !idx v; incr idx + ) settings_xml; lprintf out "default: return 0.;\n"; left ();