Changing Buck APP parameters on the fly

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hello all,

I have question regarding changing Dave app parameter on the fly.
I am using BUCK_VC_FIX_FQ app where there is Vout reference parameter which is currently set at 2V (see attached picture).
In our product, when Vout ref is 2V the output of Buck app is 200Vdc and when ref is 4V output is 400Vdc.
Is there a way we can change Vout ref based on I/O pin status on the fly. For e.g. when Pin status is High set Vout ref 2V and when low set 4V.

Thanks,

2979.attach
0 Likes
10 Replies
Not applicable
Any Comments on the question above?

Thanks,

Abhishek Sabnis
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi Abhishek Sabnis,

let´s provide you with a comment on your issue. So, if you take a look at the generated APP files ("/Dave/Generated/BUCK_VC_FIX_FQ/buck_vc_fix_fq_conf.c") you will find a structure named "BUCK_VC_FIX_FQ_0" (this is of course if you leave the default name of BUCK APP - if not just search for the structure of BUCK_VC_FIX_FQ_t type). There you can find a member of that structure named "vout_reference". This is exactly the integer representation of that value that you enter in GUI. Now, let´s check another structure used by BUCK APP. Under "Control Settings" of the APP you can select two types of controller: type II and type III. So depending which one you select you will find the structure in the same "buck_vc_fix_fq_conf.c" file that describes the configuration of the controller.
Notice "ref_ptr" member of that structure. It points to the previously mentioned "vout_reference" member of "BUCK_VC_FIX_FQ_0" structure.

So, how does this have anything with setting reference voltage on-the-fly. If you enable "Voltage Control Loop" in "Control Configuration" tab of the BUCK APP and generate the code you can open "buck_vc_fix_fq_control_loop.c" located under "/Dave/Generated/BUCK_VC_FIX_FQ".
I will copy here the code that is located inside of that file for easier understanding:

/* Control loop for BUCK_VC_FIX_FQ_0 */
void BUCK_VC_FIX_FQ_0_Control_Loop_ISR(void)
{
/* PWM phase 0 handle pointer */
PWM_CCU8_t* pwm_ccu8_app0_ptr = BUCK_VC_FIX_FQ_0.pwm_ccu8_handle_array[0];

/* Get ADC measured Vout result */
BUCK_VC_FIX_FQ_0.buck_vout = (uint32_t) XMC_VADC_GROUP_GetResult(VADC_G0, 9U);

/* Controller */
CONTROL_LIB_3P3ZFixedPoint(BUCK_VC_FIX_FQ_0.typeIII);

/* Set compare value for CC8 phase 0 */
XMC_CCU8_SLICE_SetTimerCompareMatchChannel1(pwm_ccu8_app0_ptr->ccu8_slice_ptr, (uint16_t) BUCK_VC_FIX_FQ_0.typeIII->out);

/* Transfer phase 0 compare value from shadow register to actual register */
XMC_CCU8_EnableShadowTransfer(pwm_ccu8_app0_ptr->ccu8_module_ptr, pwm_ccu8_app0_ptr->shadow_txfr_msk);

} /* end of Control loop */


Notice following line:
    /* Controller */
CONTROL_LIB_3P3ZFixedPoint(BUCK_VC_FIX_FQ_0.typeIII);


So on the each execution of the Interrupt Service Routine (currently set to be executed at Vout Result Event; tab "Interrupt Settings" under BUCK APP) controller part is using the coefficient values and also Vout reference value. You can see that to be able to change the value on-the-fly you just need to modify the value of the "vout_reference" member of "BUCK_VC_FIX_FQ_0" structure.

You have two options; either you define your control loop ISR with same code but with additional line that changes the "vout_reference" value based on pin state (not so elegant solution while you need to change the model behind BUCK APP so it doesn´t generate default control loop ISR) or you can define an interrupt that will be triggered once there is pin level transition and then inside of the interrupt service routine you can change "vout_reference" value. However beware of race conditions and that this change of the "vout_reference" value should be an atomic operation. Also, sudden change of "vout_reference" value may cause some over- or -undershotting on the Vout signal, so use overload protection that is defined under "Overload Configuration" tab in BUCK APP. At the end you need to try the chnages of the code in practice, this was just my comment on your question 🙂

Regards,
Deni
0 Likes
Not applicable
Deni,

Thank you very much for your reply.

Here are couple of comments and observation from my side:
I put Vout ref as 1V and generate code and then 2V and genrate code.
When i compared buck_vc_fix_fq_conf.c file of both 1V and 2V i found multiple diferences.
see attached code file for differences.
Also, I do not see Vout_reference has changed in both cases it remains same as 0.
since, changing any of the genreated code file is not viable option i need to copy functions in main file and then make changes on the fly.
I would be very glad if you can help me with this.

Functions from buck_vc_fix_fq_conf.c for Vout ref = 1V

const BUCK_VC_FIX_FQ_CONFIG_t BUCK_VC_FIX_FQ_0_config =
{
.adc_vout_enable = true,
.adc_vin_enable = false,
.adc_iout1_enable = false,
.adc_iout2_enable = false,
.adc_iout3_enable = false,
.adc_iout4_enable = false,
.adc_udef_enable = false,

.vin_sw_protection = false,
.vout_sw_protection = false,
.iout1_sw_protection = false,
.iout2_sw_protection = false,
.iout3_sw_protection = false,
.iout4_sw_protection = false,

.volt_control_rate = 1U,
.filter = BUCK_VC_FIX_FQ_FILTER_TYPE_II,
.interrupt_event = BUCK_VC_FIX_FQ_INTERRUPT_VOUT_RESULT_EVENT,

.vout = 1240U,
.vin = 3116U,
.gain_vout = 4095U,
.gain_vin = 857U,
.gain_iout1 = 4095U,
.gain_iout2 = 4095U,
.gain_iout3 = 4095U,
.gain_iout4 = 4095U,

.vout_high_limit = 3102U,
.vin_high_limit = 3740U,
.iout1_high_limit = 2481U,
.iout2_high_limit = 2481U,
.iout3_high_limit = 2481U,
.iout4_high_limit = 2481U,
.vout_low_limit = 620U,
.vin_low_limit = 2493U,
.iout1_low_limit = 12U,
.iout2_low_limit = 12U,
.iout3_low_limit = 12U,
.iout4_low_limit = 12U,
.soft_start_enable = true,
.volt_step_increment = 1U,
.systick_timer_period = 1000U,
.systimer_call_back = (SYSTIMER_CALLBACK_t)BUCK_VC_FIX_FQ_0_SoftStart,
};

CONTROL_LIB_2P2Z_DATA_FIXED_POINT_t BUCK_VC_FIX_FQ_0_typeII =
{
.fdbk_ptr = (int16_t *) &BUCK_VC_FIX_FQ_0.buck_vout,
.ref_ptr = (int16_t *) &BUCK_VC_FIX_FQ_0.vout_reference,

.coeff_b0 = -157433,
.coeff_b1 = 143757,
.coeff_b2 = 157286,
.coeff_a1 = 0,
.coeff_a2 = 18146,

.out_limit_max = 97536,
.out_limit_imin = -97536,
.out_limit_min = 0,

.x_0 = 0,
.x_1 = 0,
.y_0 = 0,
.y_1 = 0,

.scale_a = 6,
.scale_b = 10,
.scale_out = 7,
.out = 0,
};

Functions from buck_vc_fix_fq_conf.c for Vout ref = 2V

const BUCK_VC_FIX_FQ_CONFIG_t BUCK_VC_FIX_FQ_0_config =
{
.adc_vout_enable = true,
.adc_vin_enable = false,
.adc_iout1_enable = false,
.adc_iout2_enable = false,
.adc_iout3_enable = false,
.adc_iout4_enable = false,
.adc_udef_enable = false,

.vin_sw_protection = false,
.vout_sw_protection = false,
.iout1_sw_protection = false,
.iout2_sw_protection = false,
.iout3_sw_protection = false,
.iout4_sw_protection = false,

.volt_control_rate = 1U,
.filter = BUCK_VC_FIX_FQ_FILTER_TYPE_II,
.interrupt_event = BUCK_VC_FIX_FQ_INTERRUPT_VOUT_RESULT_EVENT,

.vout = 2481U,
.vin = 3116U,
.gain_vout = 4095U,
.gain_vin = 857U,
.gain_iout1 = 4095U,
.gain_iout2 = 4095U,
.gain_iout3 = 4095U,
.gain_iout4 = 4095U,

.vout_high_limit = 3102U,
.vin_high_limit = 3740U,
.iout1_high_limit = 2481U,
.iout2_high_limit = 2481U,
.iout3_high_limit = 2481U,
.iout4_high_limit = 2481U,
.vout_low_limit = 620U,
.vin_low_limit = 2493U,
.iout1_low_limit = 12U,
.iout2_low_limit = 12U,
.iout3_low_limit = 12U,
.iout4_low_limit = 12U,
.soft_start_enable = true,
.volt_step_increment = 2U,
.systick_timer_period = 1000U,
.systimer_call_back = (SYSTIMER_CALLBACK_t)BUCK_VC_FIX_FQ_0_SoftStart,
};

CONTROL_LIB_2P2Z_DATA_FIXED_POINT_t BUCK_VC_FIX_FQ_0_typeII =
{
.fdbk_ptr = (int16_t *) &BUCK_VC_FIX_FQ_0.buck_vout,
.ref_ptr = (int16_t *) &BUCK_VC_FIX_FQ_0.vout_reference,

.coeff_b0 = -314867,
.coeff_b1 = 287516,
.coeff_b2 = 314575,
.coeff_a1 = 0,
.coeff_a2 = 18146,

.out_limit_max = 97536,
.out_limit_imin = -97536,
.out_limit_min = 0,

.x_0 = 0,
.x_1 = 0,
.y_0 = 0,
.y_1 = 0,

.scale_a = 5,
.scale_b = 11,
.scale_out = 7,
.out = 0,
};
see parameters .vout, .volt_step_increment, .coeff_b0 , .coeff_b1 , .coeff_b2, .scale_a, .scale_b are different in both cases.
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi Abhishek Sabnis,

hmmm...looks weird to be honest. I´ve changed only the Vout ref value on the "Buck Coverter Configuration" tab:

3010.attach

And I´ve got....only those values changed...no other difference are there. You can see when I compare those generated files with a tool:

3011.attach

You can see settings of other tabs that make some impact on coefficients definition in my example project:


3012.attach
3013.attach

Also, you haven´t copied the structure that contains ".vout_reference" value...it should be under "BUCK_VC_FIX_FQ_0" structure not "BUCK_VC_FIX_FQ_0_config". But you can also see in the "BUCK_VC_FIX_FQ_0_config" structure that you posted that ".vout" value changed as it shoudl...however other values shouldn´t change so please double check your settings.
And yes, I´m running DAVE 4.3.2. and the BUCK APP version is 4.1.2.

Best regards,
Deni
0 Likes
Not applicable
Deni,

I am tweaking Buck app to work as DC-DC converter (Push-Pull converter) which converts 15VDC to 200VDC (for Vout_reference = 1V) and 15VDC to 200VDC (Vout_referece = 2V)
I changed control configuration added softstart and made it non-sychronus 2 Phase (180 apart) conveter. all MCU does is checking Vout and modifying 2 Direct PWM outputs which drivers MOSFETs to achieve respected DC voltage (200 or 400VDC).
The application works perfect for both Vout_ref, bu i would like to change Vout_reference internally. Another thing is the change of Vout_reference should be changed after power on, before Buck app starts working and once its changed remains constant then after. Only way to change it is reset MCU.
So this not excatly "on the fly" change which might cause overshoot.
See app setting as attached in picture below:
3016.attach3017.attach3018.attach3019.attach

See attached piece of code for 1V and 2V ref;



 Vout_referenece = 2V BUCK_VC_FIX_FQ_t BUCK_VC_FIX_FQ_0 =
{
.config = &BUCK_VC_FIX_FQ_0_config,
.adc_config = &BUCK_VC_FIX_FQ_0_ADCConfig,
.pwm_config = &BUCK_VC_FIX_FQ_0_PWMConfig,
.state = BUCK_VC_FIX_FQ_STATE_UNINITIALIZED,

.interrupt_config = &BUCK_VC_FIX_FQ_0_InterruptConfig,
.vout_reference = 0U,
.typeII = &BUCK_VC_FIX_FQ_0_typeII,

.group_ptr_array = {
VADC_G0,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},

.adc_scan_app_handle_array = {
&ADC_SCAN_0,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},

.pwm_ccu8_handle_array = {&PWM_CCU8_0, &PWM_CCU8_1, NULL, NULL},

.systimer_handle = &SYSTIMER_0,

};


BUCK_VC_FIX_FQ_t BUCK_VC_FIX_FQ_0 =
{
.config = &BUCK_VC_FIX_FQ_0_config,
.adc_config = &BUCK_VC_FIX_FQ_0_ADCConfig,
.pwm_config = &BUCK_VC_FIX_FQ_0_PWMConfig,
.state = BUCK_VC_FIX_FQ_STATE_UNINITIALIZED,

.interrupt_config = &BUCK_VC_FIX_FQ_0_InterruptConfig,
.vout_reference = 0U,
.typeII = &BUCK_VC_FIX_FQ_0_typeII,

.group_ptr_array = {
VADC_G0,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},

.adc_scan_app_handle_array = {
&ADC_SCAN_0,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
},

.pwm_ccu8_handle_array = {&PWM_CCU8_0, &PWM_CCU8_1, NULL, NULL},

.systimer_handle = &SYSTIMER_0,

};


There is no difrrence in the code.

Another idea i tried, add another BUCK_VC_FIX_FQ app as BUCK_VC_FIX_FQ_1 and set diffrent Vout_ref for each. But issue is you can not share PWM_CCU8 between two instances of Buck app.
See attached picture of app dependancy.
3020.attach
0 Likes
Not applicable
Deni,

Any recommendations?
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi,

my initial comment is still valid. So I must correct myself while I haven´t used exactly the same configuration as you, but that wasn´t possible until you uploaded the photos of your APP settings. So, you´re using soft start feature....that explains a lot of things. First you can see that vout_reference value is 0. And that makes sense. Soft start means that the value with be incremented from 0 to final voltage reference value that you wrote into GUI...in your case let´s say you want first to use 1 V. If you open "buck_vc_fix_fq_control_loop.c" file you can see "BUCK_VC_FIX_FQ_0_SoftStart" function where the value of vout_reference will become the value as is it specified in GUI, in this case representative value of 1 V.
And then you can try to change this value inside "BUCK_VC_FIX_FQ_0_Control_Loop_ISR" function located in the same .c file. Refer to my initial comment for more details. As I mentioned initially, I´m not saying this will work, I´m just trying to give a comment that may be helpful 🙂

Regards,
Deni
0 Likes
Not applicable
Deni,

Any recommendations?
0 Likes
Not applicable
Deni,

After several attempts of trial and error, i finally got some good results and was able to change Vout_reference based on I/O decision.

Here is what added new function with Vout_reference =2481U (App is loaded with Vout_referernce = 1000U) function:

void BUCK_VC_FIX_FQ_0_SoftStartxx(BUCK_VC_FIX_FQ_t * handle_ptr)
{
SYSTIMER_STATUS_t status = SYSTIMER_STATUS_FAILURE;

handle_ptr->vout_reference += 2U; /* Step increment the reference voltage */

// if (handle_ptr->vout_reference >= handle_ptr->config->vout)
//{
handle_ptr->vout_reference = 2481U; /* This is final step of Vref increment. Ensures Vref is not more than expected Vout */

handle_ptr->soft_start_complete = true; /* Soft start completed */

status = SYSTIMER_StopTimer(handle_ptr->software_timer_id); /* Stop software timer */

if (status == SYSTIMER_STATUS_SUCCESS)
{
handle_ptr->software_timer_status = BUCK_VC_FIX_FQ_SW_TIMER_STOP_SUCCESS; /* Software timer is stopped successfully */
}
else
{
handle_ptr->software_timer_status = BUCK_VC_FIX_FQ_SW_TIMER_STOP_FAILED; /* Failed to stop software timer */
}
// }
}


This function will be called when I/O status is high and if low then will not be called.

Let me know if this method is viable solution considering, i am overridding some functions in app.

Thanks,

Abhishek Sabnis
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi Abhishek Sabnis,

sure, if its working for you it´s completely fine to override certain functions generated by the APP. At the end APP cannot cover all the possible use cases, so in your case it´s perfectly fine to replace some of the generated code.

Regards,
Deni
0 Likes