diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h index 2414342d352dd6637cb9cda485b5c85b865886b3..c459aa8b11070cfc938a0d4ee744244ed6fe9190 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h @@ -69,6 +69,8 @@ typedef enum { MSTR = LL_HRTIM_TIMER_MASTER } hrtim_tu_t; +typedef void(*hrtim_callback_t)(); + /** * @brief Set the duty-cycle, dead-time and phase shift for a given @@ -97,7 +99,7 @@ void hrtim_update_adc_trig_interleaved(uint16_t new_trig, hrtim_tu_t leg1_tu, hr /** * @brief Enable interrupt on repetition counter for the chosen timing unit * @param tu_src timing unit which will be the source for the ISR: - * @arg @ref MSTR + * @arg @ref MSTR * @arg @ref TIMA * @arg @ref TIMB * @arg @ref TIMC @@ -107,13 +109,15 @@ void hrtim_update_adc_trig_interleaved(uint16_t new_trig, hrtim_tu_t leg1_tu, hr * @param repetition value between 1 and 256 for the repetition counter: * period of the event wrt. periods of the HRTIM. * E.g. when set to 10, one event will be triggered every 10 HRTIM period. + * @param callback Pointer to a void(void) function that will be called + * when the event is triggerred. */ -void hrtim_PeriodicEvent_en(hrtim_tu_t tu_src, uint32_t repetition); +void hrtim_PeriodicEvent_en(hrtim_tu_t tu_src, uint32_t repetition, hrtim_callback_t callback); /** * @brief Disable interrupt on repetition counter for the chosen timing unit * @param tu_src timing unit which will be the source for the ISR: - * @arg @ref MSTR + * @arg @ref MSTR * @arg @ref TIMA * @arg @ref TIMB * @arg @ref TIMC @@ -126,7 +130,7 @@ void hrtim_PeriodicEvent_dis(hrtim_tu_t tu_src); /** * @brief Change the repetition counter value to control the ISR interrupt * @param tu_src timing unit which will be the source for the ISR: - * @arg @ref MSTR + * @arg @ref MSTR * @arg @ref TIMA * @arg @ref TIMB * @arg @ref TIMC diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h index f99a5e8cdde6597d78408a7ca89b9f993ec286d4..60608468566a0b6b5b793318f9f16da084bf5b35 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022 LAAS-CNRS + * Copyright (c) 2020-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -25,11 +25,12 @@ * * @file * @brief PWM management layer by inverter leg interface definitions - * @date 2022 + * @date 2023 * @author Hugues Larrive <hugues.larrive@laas.fr> * @author Antoine Boche <antoine.boche@laas.fr> * @author Luiz Villa <luiz.villa@laas.fr> * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> + * @author Clément Foucher <clement.foucher@laas.fr> */ #ifndef LEG_H_ @@ -65,7 +66,7 @@ typedef struct { * @brief Initializes all the configured devices with the chosen switch convention * * @param[in] leg1_upper_switch_convention Choice of the switch convention for leg 1 - * @param[in] leg2_upper_switch_convention Choice of the switch convention for leg 2 + * @param[in] leg2_upper_switch_convention Choice of the switch convention for leg 2 * * @return HRTIM period */ @@ -75,7 +76,7 @@ uint16_t leg_init(bool leg1_upper_switch_convention, bool leg2_upper_switch_conv * @brief Initializes all the configured devices with up-down mode and the chosen switch convention * * @param[in] leg1_upper_switch_convention Choice of the switch convention for leg 1 - * @param[in] leg2_upper_switch_convention Choice of the switch convention for leg 2 + * @param[in] leg2_upper_switch_convention Choice of the switch convention for leg 2 * * @return HRTIM period */ @@ -111,15 +112,22 @@ void leg_stop(hrtim_tu_t timing_unit); * * @param[in] timing_unit timing_unit from TIMA to TIMF */ -void leg_start(hrtim_tu_t timing_unit); +void leg_start(hrtim_tu_t timing_unit); /** * @brief period getter * - * @return period in micro-seconds value returned by leg_init() + * @return period counter within the register */ uint16_t leg_period(void); +/** + * @brief period getter + * + * @return period in micro-seconds + */ +uint32_t leg_get_period_us(); + /** * @brief LEG_NUMOF getter * diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c b/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c index b4762e88c94c4cf01665ecbb574db740099529f8..40d30a96037208246a751842f196acad27178b1c 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c @@ -32,14 +32,21 @@ #include "leg.h" +// HRTIM interrupts +static const uint8_t HRTIM_IRQ_NUMBER = 67; +static const uint8_t HRTIM_IRQ_PRIO = 0; +static const uint8_t HRTIM_IRQ_FLAGS = 0; +static hrtim_callback_t user_callback = NULL; + + void _hrtim_init_events(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) -{ +{ if(leg1_tu == TIMA && leg2_tu == TIMB){ - hrtim_adc_trigger_en(1, 1, LL_HRTIM_ADCTRIG_SRC13_TIMACMP3); - hrtim_adc_trigger_en(3, 2, LL_HRTIM_ADCTRIG_SRC13_TIMBCMP4); + hrtim_adc_trigger_en(1, 1, LL_HRTIM_ADCTRIG_SRC13_TIMACMP3); + hrtim_adc_trigger_en(3, 2, LL_HRTIM_ADCTRIG_SRC13_TIMBCMP4); }else if(leg1_tu == TIMA && leg2_tu == TIMC){ - hrtim_adc_trigger_en(3, 1, LL_HRTIM_ADCTRIG_SRC13_TIMACMP3); - hrtim_adc_trigger_en(1, 3, LL_HRTIM_ADCTRIG_SRC13_TIMCCMP4); + hrtim_adc_trigger_en(3, 1, LL_HRTIM_ADCTRIG_SRC13_TIMACMP3); + hrtim_adc_trigger_en(1, 3, LL_HRTIM_ADCTRIG_SRC13_TIMCCMP4); } hrtim_update_adc_trig_interleaved(1, leg1_tu, leg2_tu); @@ -48,47 +55,63 @@ void _hrtim_init_events(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) void _hrtim_init_events_center_aligned(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) { if(leg1_tu == TIMA && leg2_tu == TIMB){ - // setting the adc roll-over mode on period event - LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_ROLLOVER_MODE_PER); - LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_ROLLOVER_MODE_PER); - - // setting adc trigger - hrtim_adc_trigger_en(1, 1, LL_HRTIM_ADCTRIG_SRC13_TIMAPER); - hrtim_adc_trigger_en(3, 2, LL_HRTIM_ADCTRIG_SRC13_TIMBPER); + // setting the adc roll-over mode on period event + LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_ROLLOVER_MODE_PER); + LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_ROLLOVER_MODE_PER); + + // setting adc trigger + hrtim_adc_trigger_en(1, 1, LL_HRTIM_ADCTRIG_SRC13_TIMAPER); + hrtim_adc_trigger_en(3, 2, LL_HRTIM_ADCTRIG_SRC13_TIMBPER); }else if(leg1_tu == TIMA && leg2_tu == TIMC){ - // setting the adc roll-over mode on period event - LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_ROLLOVER_MODE_PER); - LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_C, LL_HRTIM_ROLLOVER_MODE_PER); - - // setting adc trigger - hrtim_adc_trigger_en(3, 1, LL_HRTIM_ADCTRIG_SRC13_TIMAPER); - hrtim_adc_trigger_en(1, 3, LL_HRTIM_ADCTRIG_SRC13_TIMCPER); + // setting the adc roll-over mode on period event + LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_ROLLOVER_MODE_PER); + LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_C, LL_HRTIM_ROLLOVER_MODE_PER); + + // setting adc trigger + hrtim_adc_trigger_en(3, 1, LL_HRTIM_ADCTRIG_SRC13_TIMAPER); + hrtim_adc_trigger_en(1, 3, LL_HRTIM_ADCTRIG_SRC13_TIMCPER); + } +} + +void _hrtim_callback() +{ + LL_HRTIM_ClearFlag_REP(HRTIM1,LL_HRTIM_TIMER_MASTER); + if (user_callback != NULL) + { + user_callback(); } } void hrtim_update_adc_trig_interleaved(uint16_t new_trig, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) { if(leg1_tu == TIMA && leg2_tu == TIMB){ - hrtim_cmp_set(0, TIMA, CMP3xR, new_trig); - hrtim_cmp_set(0, TIMB, CMP4xR, new_trig); + hrtim_cmp_set(0, TIMA, CMP3xR, new_trig); + hrtim_cmp_set(0, TIMB, CMP4xR, new_trig); }else if(leg1_tu == TIMA && leg2_tu == TIMC){ - hrtim_cmp_set(0, TIMA, CMP3xR, new_trig); - hrtim_cmp_set(0, TIMC, CMP4xR, new_trig); + hrtim_cmp_set(0, TIMA, CMP3xR, new_trig); + hrtim_cmp_set(0, TIMC, CMP4xR, new_trig); } } -void hrtim_PeriodicEvent_en(hrtim_tu_t tu_src, uint32_t repetition) +void hrtim_PeriodicEvent_en(hrtim_tu_t tu_src, uint32_t repetition, hrtim_callback_t callback) { + /* Memorize user callback */ + user_callback = callback; + /* Set repetition counter to repetition-1 so that an event * is triggered every "repetition" number of periods. */ LL_HRTIM_TIM_SetRepetition(HRTIM1, tu_src, repetition-1); LL_HRTIM_EnableIT_REP(HRTIM1, tu_src); /* Enabling the interrupt on repetition counter event*/ + + IRQ_CONNECT(HRTIM_IRQ_NUMBER, HRTIM_IRQ_PRIO, _hrtim_callback, NULL, HRTIM_IRQ_FLAGS); + irq_enable(HRTIM_IRQ_NUMBER); } void hrtim_PeriodicEvent_dis(hrtim_tu_t tu_src) { + irq_disable(HRTIM_IRQ_NUMBER); LL_HRTIM_DisableIT_REP(HRTIM1, tu_src); /* Disabling the interrupt on repetition counter event*/ } diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp index c61575aa78bb4053fab4c9c626e55e95fb156071..0874fe2745110a4e4ede580cd25c82ce3c93f4de 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022 LAAS-CNRS + * Copyright (c) 2020-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -21,11 +21,12 @@ /** * @file * @brief PWM management layer by inverter leg - * @date 2022 + * @date 2023 * @author Hugues Larrive <hugues.larrive@laas.fr> * @author Antoine Boche <antoine.boche@laas.fr> * @author Luiz Villa <luiz.villa@laas.fr> * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> + * @author Clément Foucher <clement.foucher@laas.fr> */ #include "leg.h" @@ -53,23 +54,23 @@ static uint8_t _TU_num(hrtim_tu_t tu){ switch(tu){ case TIMA: return 0; - + case TIMB: return 1; - - case TIMC: + + case TIMC: return 2; - + case TIMD: return 3; break; - + case TIME: - return 4; - - case TIMF: + return 4; + + case TIMF: return 5; - + default: return 100; @@ -100,7 +101,7 @@ uint16_t leg_init(bool leg1_upper_switch_convention, bool leg2_upper_switch_conv /** * This function Initialize the hrtim and all the legs * with the chosen convention for the switch controlled - * on the power converter to a frequency of 200kHz + * on the power converter to a frequency of 200kHz * with the counter on up-down mode (center-alligned) * Must be initialized in first position */ @@ -155,7 +156,7 @@ void leg_set_dt(hrtim_tu_t timing_unit, uint16_t rise_ns, uint16_t fall_ns) void leg_stop(hrtim_tu_t timing_unit) { hrtim_out_dis(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT1); - hrtim_out_dis(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT2); + hrtim_out_dis(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT2); } void leg_start(hrtim_tu_t timing_unit) @@ -169,6 +170,11 @@ uint16_t leg_period(void) return period; } +uint32_t leg_get_period_us() +{ + return period*184e-6; +} + uint8_t leg_numof(void) { return LEG_NUMOF; diff --git a/zephyr/modules/owntech_scheduling/zephyr/Kconfig b/zephyr/modules/owntech_scheduling/zephyr/Kconfig index de1af3274c87c31149885b9fd0375af6c72e739a..2ee522e6e1761411ffcfbadddd8bdd2ae47be177 100644 --- a/zephyr/modules/owntech_scheduling/zephyr/Kconfig +++ b/zephyr/modules/owntech_scheduling/zephyr/Kconfig @@ -2,6 +2,7 @@ config OWNTECH_SCHEDULING bool "Enable OwnTech scheduling" default y depends on OWNTECH_TIMER_DRIVER + depends on OWNTECH_HRTIM_DRIVER if OWNTECH_SCHEDULING diff --git a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp index 5189e667c728126281ede7c9e0bb90d6a3c52478..4ade5ce20c9995b3388e565f7a38422eb1c5718e 100644 --- a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp +++ b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 LAAS-CNRS + * Copyright (c) 2022-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,7 +18,7 @@ */ /** - * @date 2022 + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> */ @@ -49,8 +49,9 @@ Scheduling scheduling; // Non-interruptible control task -int8_t Scheduling::defineUninterruptibleSynchronousTask(void (*periodic_task)(), uint32_t task_period_us) +int8_t Scheduling::defineUninterruptibleSynchronousTask(task_function_t periodic_task, uint32_t task_period_us, scheduling_interrupt_source_t int_source) { + scheduling_set_uninterruptible_synchronous_task_interrupt_source(int_source); return scheduling_define_uninterruptible_synchronous_task(periodic_task, task_period_us); } diff --git a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h index 1ebff44b450f85f67a912e4731f8977940789abf..ad10b66803f5f9beddd735e4ddb2da1d4a785ac9 100644 --- a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h +++ b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 LAAS-CNRS + * Copyright (c) 2022-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,7 +18,7 @@ */ /** - * @date 2022 + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> */ @@ -35,6 +35,9 @@ typedef void (*task_function_t)(); +enum class scheduling_interrupt_source_t { source_hrtim, source_tim6 }; + + ///// // Static class definition @@ -56,18 +59,24 @@ public: * to be executed periodically. * @param task_period_us Period of the function in µs. * Allowed range: 1 to 6553 µs. - * Value is ignored if first parameter is NULL. + * If interrupt source is HRTIM, this value MUST be an + * integer multiple of the HRTIM period. + * @param int_source Interrupt source that triggers the task. + * By default, the HRTIM is the source, but this optional + * parameter can be provided to set TIM6 as the source in + * case the HRTIM is not used or if the task can't be + * correlated to an HRTIM event. * @return 0 if everything went well, - * -1 if there was an error defining the task. - * An error can occur notably when an uninterruptible - * task has already been defined previously. + * -1 if there was an error defining the task. + * An error can occur notably when an uninterruptible + * task has already been defined previously. */ - int8_t defineUninterruptibleSynchronousTask(void (*periodic_task)(), uint32_t task_period_us); + int8_t defineUninterruptibleSynchronousTask(task_function_t periodic_task, uint32_t task_period_us, scheduling_interrupt_source_t int_source = scheduling_interrupt_source_t::source_hrtim); /** * @brief Use this function to start the previously defined * uninterruptible synchronous task. - */ + */ void startUninterruptibleSynchronousTask(); /** @@ -88,11 +97,11 @@ public: * * @param routine Pointer to the void(void) function * that will act as the task main function. - * @return Number assigned to the task. Will be -1 - * if max number of asynchronous task has been reached. - * In such a case, the task definition is cancelled. - * Increase maximum number of asynchronous tasks in - * prj.conf if required. + * @return Number assigned to the task. Will be -1 if max + * number of asynchronous task has been reached. + * In such a case, the task definition is ignored. + * Increase maximum number of asynchronous tasks + * in prj.conf if required. */ int8_t defineAsynchronousTask(task_function_t routine); @@ -100,9 +109,8 @@ public: * @brief Use this function to start a previously defined * asynchronous task using its task number. * - * @param task_number - * Number of the task to start, obtained using the - * defineAsynchronousTask() function. + * @param task_number Number of the task to start, obtained + * using the defineAsynchronousTask() function. */ void startAsynchronousTask(uint8_t task_number); @@ -112,9 +120,8 @@ public: * The task can be then resumed by calling * startAsynchronousTask() again. * - * @param task_number - * Number of the task to stop, obtained using the - * defineAsynchronousTask() function. + * @param task_number Number of the task to start, obtained + * using the defineAsynchronousTask() function. */ void stopAsynchronousTask(uint8_t task_number); diff --git a/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.cpp b/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.cpp index 8e6da288696759463af795b5708ce3b3c9d43596..2eb0b4098e73231aaba7c4164606cc87cebbd1f2 100644 --- a/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.cpp +++ b/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 LAAS-CNRS + * Copyright (c) 2022-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,18 +18,22 @@ */ /** - * @date 2022 + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> */ +// Current module +#include "scheduling_common.hpp" + // OwnTech Power API #include "timer.h" -#include "scheduling_common.hpp" +#include "leg.h" +#include "hrtim.h" ///// -// Local variables +// Local variables and constants // Timer device static const struct device* timer6 = DEVICE_DT_GET(TIMER6_DEVICE); @@ -37,60 +41,113 @@ static const struct device* timer6 = DEVICE_DT_GET(TIMER6_DEVICE); // Task status static task_status_t uninterruptibleTaskStatus = task_status_t::inexistent; +// Interrupt source +static scheduling_interrupt_source_t interrupt_source = scheduling_interrupt_source_t::source_hrtim; + +// For HRTIM interrupts +static uint32_t repetition = 0; +static task_function_t user_periodic_task = NULL; + ///// -// API +// Public API -int8_t scheduling_define_uninterruptible_synchronous_task(void (*periodic_task)(), uint32_t task_period_us) + +void scheduling_set_uninterruptible_synchronous_task_interrupt_source(scheduling_interrupt_source_t int_source) { - if (device_is_ready(timer6) == true) + interrupt_source = int_source; +} + +int8_t scheduling_define_uninterruptible_synchronous_task(task_function_t periodic_task, uint32_t task_period_us) +{ + if ( (uninterruptibleTaskStatus != task_status_t::inexistent) && (uninterruptibleTaskStatus != task_status_t::suspended)) + return -1; + + if (periodic_task == NULL) + return -1; + + if (interrupt_source == scheduling_interrupt_source_t::source_tim6) { - if ( (uninterruptibleTaskStatus == task_status_t::inexistent) || (uninterruptibleTaskStatus == task_status_t::suspended)) - { - // Configure and start timer + if (device_is_ready(timer6) == false) + return -1; - struct timer_config_t timer_cfg = {0}; - timer_cfg.timer_enable_irq = 1; - timer_cfg.timer_irq_callback = periodic_task; - timer_cfg.timer_irq_t_usec = task_period_us; + // Everything OK, go on with timer configuration + struct timer_config_t timer_cfg = {0}; + timer_cfg.timer_enable_irq = 1; + timer_cfg.timer_irq_callback = periodic_task; + timer_cfg.timer_irq_t_usec = task_period_us; - timer_config(timer6, &timer_cfg); + timer_config(timer6, &timer_cfg); - uninterruptibleTaskStatus = task_status_t::defined; + uninterruptibleTaskStatus = task_status_t::defined; - return 0; - } - else - { - return -1; - } + return 0; } - else + else if (interrupt_source == scheduling_interrupt_source_t::source_hrtim) { - return -1; + uint32_t hrtim_period_us = leg_get_period_us(); + + if (task_period_us % hrtim_period_us != 0) + return -1; + + repetition = task_period_us / hrtim_period_us; + + if (repetition == 0) + return -1; + + user_periodic_task = periodic_task; + + uninterruptibleTaskStatus = task_status_t::defined; + + return 0; } + + return -1; } void scheduling_start_uninterruptible_synchronous_task() { - if (device_is_ready(timer6) == true) + if ( (uninterruptibleTaskStatus != task_status_t::defined) && (uninterruptibleTaskStatus != task_status_t::suspended) ) + return; + + if (interrupt_source == scheduling_interrupt_source_t::source_tim6) { - if ( (uninterruptibleTaskStatus == task_status_t::defined) || (uninterruptibleTaskStatus == task_status_t::suspended) ) - { - timer_start(timer6); - uninterruptibleTaskStatus = task_status_t::running; - } + if (device_is_ready(timer6) == false) + return; + + timer_start(timer6); + + uninterruptibleTaskStatus = task_status_t::running; + } + else if (interrupt_source == scheduling_interrupt_source_t::source_hrtim) + { + if ( (repetition == 0) || (user_periodic_task == NULL) ) + return; + + hrtim_PeriodicEvent_en(MSTR, repetition, user_periodic_task); + + uninterruptibleTaskStatus = task_status_t::running; } } void scheduling_stop_uninterruptible_synchronous_task() { - if (device_is_ready(timer6) == true) + if (uninterruptibleTaskStatus != task_status_t::running) + return; + + if (interrupt_source == scheduling_interrupt_source_t::source_tim6) { - if (uninterruptibleTaskStatus == task_status_t::running) - { - timer_stop(timer6); - uninterruptibleTaskStatus = task_status_t::suspended; - } + if (device_is_ready(timer6) == false) + return; + + timer_stop(timer6); + + uninterruptibleTaskStatus = task_status_t::suspended; + } + else if (interrupt_source == scheduling_interrupt_source_t::source_hrtim) + { + hrtim_PeriodicEvent_dis(MSTR); + + uninterruptibleTaskStatus = task_status_t::suspended; } } diff --git a/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.hpp b/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.hpp index 6134011207770134ead65996add603960aee6bb2..e64ac15d00aeba242d3d9f750ab19475f8613ae8 100644 --- a/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.hpp +++ b/zephyr/modules/owntech_scheduling/zephyr/src/uninterruptible_synchronous_task.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 LAAS-CNRS + * Copyright (c) 2022-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,7 +18,7 @@ */ /** - * @date 2022 + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> */ @@ -30,7 +30,8 @@ #include "Scheduling.h" -int8_t scheduling_define_uninterruptible_synchronous_task(void (*periodic_task)(), uint32_t task_period_us); +void scheduling_set_uninterruptible_synchronous_task_interrupt_source(scheduling_interrupt_source_t int_source); +int8_t scheduling_define_uninterruptible_synchronous_task(task_function_t periodic_task, uint32_t task_period_us); void scheduling_start_uninterruptible_synchronous_task(); void scheduling_stop_uninterruptible_synchronous_task();