GD3000 initialisation with NXP MBDT Toolbox for PMSM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

GD3000 initialisation with NXP MBDT Toolbox for PMSM

2,785 Views
stuart_jobbins
Contributor II

Using NXP MBD Toolbox for PMSM (Closed Loop) Motor Control ... but equally applicable to the Open loop model.

The static configuration of the PWM outputs is 'complementary mode' in both cases.

The initialisation sequence for the GD3000 requires independent control and activation of LS and HS drivers during steps t3, t4, t5 and t6... which the code cannot respect as it only has control of a single input to PWM.

The outcome is that during initialisation a large (uncontrolled and non-PWM) current is present in the motor (which may not be a problem on a small Linix Motor, but is quite significant with a 200A inverter/motor set-up) until the PWM waveforms are running.

As the interrupts for the system are triggered by PWM reload (which in turn triggers the CTU and then ADC modules), it is not viable to turn on the PWM initialisation earlier.

It is not apparently possible to change the PWM configuration dynamically between independent and complementary mode...

...so how is the GD3000 initialisation sequence to be respected?

Regards,

Stuart

14 Replies

2,221 Views
stuart_jobbins
Contributor II

Having re-read the entire chapter on FlexPWM in the PRM I now think the right answer is to use the SelectSwCtrlOutput, SelectDeadtimeSource and ForcePWMOutput to do the job...

... but I don't see how to manipulate HS and LS drive independntly when I'm in 'complementary mode'.. so still unsure how you achieve the GD3000 initialisation requirements.

I note no-one has fundamentally answered the question about why the MBDT models DON'T respect the GD3000 initialisation requirements... which seem to be pretty detailed of what AND WHY.

Do I take the lack of interaction to mean that MPC5744P is NOT a real choice for industry? Maybe I have to ask my old friend who happens to be VP and General Manager, Vehicle Dynamics Products at NXP Semi!

Regards,

Stuart

0 Kudos

2,221 Views
dumitru-daniel_
NXP Employee
NXP Employee

Hi Stuart, 

In general we try to answer all questions in this community and help all of the users ASAP. In same cases our support might take longer due to the pending number of the requests, complexity (HW & SW) of the issues, and occasional engineering workloads.

I note no-one has fundamentally answered the question about why the MBDT models DON'T respect the GD3000 initialisation requirements... which seem to be pretty detailed of what AND WHY.

The GD3000 is a standalone part - we call it external device, hence it is not supported "as is" by the MPC57xx Toolbox. Anyhow, since for the motor control we needed a piece of HW to create a demo, we have used the SPI to configure the GD3000 but we did only the minimal setup to have it working. There might be multiple reasons and excuses why we did it that way - but the only thing i want to mention is that all the examples shipped with the toolbox are intended to showcase various functionalities of the Simulink Blocksets rather than being a reference motor control design. This is clearly stated by our disclaimer.

In terms of initialization, in think you have summarized the limitations quite well. Since MBDT is a high level of abstraction, it is not always possible to address all combinations and variants. FYI, in case of the S32K1xx we have made the effort to enable special blocks for GD3000 initialization just to help end users with such scenarios. Most likely (based on your feedback) that will be considered for the next release of MPC57xx as well.

To come back to your problem: 

i) One approach you could consider is to:

- use the PWM pins as generic IOs during Simulink Initialization

- do the GD3000 setup with IO functionality

- use Block Priority to initialize the PWM functions after GD3000 IO pin initialization

With custom code from MATLAB, that should be fully attainable.

ii) Another approach would be to use a hybrid development flow: use the MBDT to generate only the code for control loops, and then link the generated files in a IDE project that will link, compile and download the final application.

This way you could control the initialization sequence in a board setup function and you will have full control over it.

Do I take the lack of interaction to mean that MPC5744P is NOT a real choice for industry?

I would not say that... In fact MPC5744P is specially designed to address the needs for Motor Control applications/systems. The main reason why S32K is much more discussed than MPC57xx, i think it is related with the fact that ARM technologies are nowadays more "trendy" in the industry and academia. Overall, based on our download statistics, Power Architecture is as popular as ARM Architecture within our toolbox users.

 Maybe I have to ask my old friend who happens to be VP and General Manager, Vehicle Dynamics Products at NXP Semi!

In general we consider any feedback from our users. That's the only way to improve and move forward. To draw a parallel with control system theory, - feedback is way to improve the system stability.

Looking forward for further interactions.

Best regards,

Daniel

0 Kudos

2,221 Views
stuart_jobbins
Contributor II

So I've managed to create an S-Function that allows me to construct some code, but even if I revert my build to 'independent' mode PWM (rather than Complementary) and use the FLEXPWM_DRV_UpdatePulseWidth (with a 100% period tick count, or 0% tick count) and follow it with a FLEXPWM_DRV_LoadCommands, there is no apparent action at the PWM output.

I can see my progress by waggling a GPIO line, and can see the code has been included/built/run but is there something I am missing to get the outputs to change?

e.g. Do I need to also use FLEXPWM_DRV_ForcePwmOutput, or as you suggested earlier...

the FLEXPWM_DRVMaskOutput and FLEXPWM_DRV_ForceApplyMask? As far as I can tell these just let the PWM outputs propagate out, rather than change the output state (High/Low).

I can't see anything that suggests the PWM outputs have been masked, as later on my software drives them OK (but has significant initial problems as the GD3000 is not driving the HS FETS correctly and they are essentially ON by default (after EN), rather than OFF (since RST)... which I'm still assuming is because the initialisation sequence for the GD3000 is incorrect!).

Basically as soon as I assert LS FETS 'On' during the t3 state of the GD3000 initialisation, the supply gets 'shorted' by the fact both HS and LS FETS (of the same phase) are in conduction! even though all the PWM inputs to the GD3000 HS (HS_B) are all High (Off).

Maybe I am reading the GD3000 spec wrong, and this is to be expected (but would appear unsafe), but the application of LS on needs to be 'momentary' to enable the bootstrap to pick up?... but the specs says HS logic is disabled until AFTER the LS pulse,and then HS pulse. By 'disabled' I expect to see HS OFF!

In the NXP MBDT model of FET initialisation Logic the scheduling (100us) means that state change by model means will have a minimum 100us period.

Regards,

Stuart

0 Kudos

2,221 Views
stuart_jobbins
Contributor II

Thanks Marius, 

I think I got past that last night.

I am now left with a simple model and a simpel bit of C Code, which I think I have all teh header dependencies sorted (with local copies ccahed from earlier builds)...

GD3000_Library_tab.png

...but I still don't know how to connect to the FlexPWM Functions (i.e. resolve the external function calls to them) or connect with the FlexPWM0_Sub Module (0,1,2) data structures.

As you will see these come up as unresolved external references.

GD3000_Build_tab.png

The text in the External reference part of the Libraries tab gives you my problem areas. I'm not even sure if this is the right place to declare them to the S Function (as it seems to need to resolve them). The Matlab S Function examples don't attempt anything like this.

Bottom right box in Library tab...

*******

* declaration for the only extern func */
void HS_LS_action(void);


/* ************* NOT SURE HOW TO DO THE REST OF EXTERNAL LINKAGES ************** */

/* Makes use of functions that have to be public (declared in flexpwm_driver)
- Prototypes below */
/* FLEXPWM_DRV_UpdatePulseWidth(); */

/* void FLEXPWM_DRV_UpdatePulseWidth(const uint32_t instance, const flexpwm_module_t subModule, const uint16_t pwmAPulseWidth,
const uint16_t pwmBPulseWidth, const flexpwm_signal_type_t pwmType);
*/
/* FLEXPWM_DRV_LoadCommands(); */
void FLEXPWM_DRV_LoadCommands(const uint32_t instance, const uint32_t subModules);
/* FLEXPWM_DRV_SetupPwm(); */
/* void FLEXPWM_DRV_SetupPwm(const uint32_t instance, const flexpwm_module_t subModule,
flexpwm_module_setup_t * const moduleSetupParams,
const flexpwm_module_signal_setup_t * const signalParams);
*/


/* ...and Public data */
/* flexPWM0_ModuleSeup0, and ..Setup1 and ..Setup2 */
/* flexPWM0_SignalSetup0, and ..Setup1 and ..Setup2 */

/*flexpwm0_0_module_setup_t declaration */
/* extern flexpwm_module_setup_t flexPWM0_ModuleSetup0; */

/*flexpwm0_0_module_signal_setup_t declaration */
/* extern flexpwm_module_signal_setup_t flexPWM0_SignalSetup0; */

/*flexpwm0_1_module_setup_t declaration */
/* extern flexpwm_module_setup_t flexPWM0_ModuleSetup1; */

/*flexpwm0_1_module_signal_setup_t declaration */
/* extern flexpwm_module_signal_setup_t flexPWM0_SignalSetup1; */

/*flexpwm0_2_module_setup_t declaration */
/* extern flexpwm_module_setup_t flexPWM0_ModuleSetup2; */

/*flexpwm0_2_module_signal_setup_t declaration */
/* extern flexpwm_module_signal_setup_t flexPWM0_SignalSetup2; */

************

Any guidance would be appreciated.

Happy to send you a cut-down model and the code (I fixed the syntactic errors from previously)...

Regards,

Stuart

0 Kudos

2,221 Views
stuart_jobbins
Contributor II

Marius,

I think the following code snippet gives you an idea of what I am trying to do to match the GD3000 initialisation specification need...

...but I'm not sure changing the channel pair mode setting will achieved the desired result, but the idea is to launch it from within the GD3000 set-up to replace states t3 to t6, to get the required LS and HS drive toggles.

Phases A, B andC on PWM0, Submodules 0, 1 and 2 respectively.

The real question is how I get these functions into the 'build system'... I can enclose as an S-function, but can't integrate into the build tlc.

Regards,

Stuart

/* Function to allow us to alter all 3 PWM0 Submodules (0, 1 and 2) corresponding to PhA, B and C, duty cycles */
*/
void Force_HS_LS_Drive(volatile uint16_t DutyA, volatile uint16_t DutyB)
{

FLEXPWM_DRV_UpdatePulseWidth (INST_FLEXPWM0, FlexPwmModule0, DutyA, DutyB, FlexPwmCentreAligned);
FLEXPWM_DRV_LoadCommands(INST_FLEXPWM0, (1 << FlexPwmModule0));
FLEXPWM_DRV_UpdatePulseWidth (INST_FLEXPWM0, FlexPwmModule1, DutyA, DutyB, FlexPwmCentreAligned);
FLEXPWM_DRV_LoadCommands(INST_FLEXPWM0, (1 << FlexPwmModule1));
FLEXPWM_DRV_UpdatePulseWidth (INST_FLEXPWM0, FlexPwmModule2, DutyA, DutyB, FlexPwmCentreAligned);
FLEXPWM_DRV_LoadCommands(INST_FLEXPWM0, (1 << FlexPwmModule2));
}

/* --------- */

/* Modify Channel Mode of Operation to Independent on submodules0, 1 and 2 of PWM0 */
void Modify_PWM_Op_Ind()
{
/* Modify the Channel Pair operation and re-init submodule */
flexPWM0_ModuleSetup0->chnlPairOper = FlexPwmIndependent;
flexPWM0_ModuleSetup1->chnlPairOper = FlexPwmIndependent;
flexPWM0_ModuleSetup2->chnlPairOper = FlexPwmIndependent;

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule0, &flexPWM0_ModuleSetup0,
&flexPWM0_SignalSetup0);
/* flexPWM0_SignalSetup0_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule0_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule0); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config1' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule1, &flexPWM0_ModuleSetup1,
&flexPWM0_SignalSetup1);
/*flexPWM0_SignalSetup1_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule1_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule1); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config2' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule2, &flexPWM0_ModuleSetup2,
&flexPWM0_SignalSetup2);
/* flexPWM0_SignalSetup2_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule2_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule2); */
}

/* --------- */


/* Modify Channel Mode of Operation to Complementary on submodules0, 1 and 2 of PWM0 */
void Modify_PWM_Op_Comp()
{
/* Modify the Channel Pair operation back to comlementary and re-init submodule */
flexPWM0_ModuleSetup0->chnlPairOper = FlexPwmComplementary;
flexPWM0_ModuleSetup1->chnlPairOper = FlexPwmComplementary;
flexPWM0_ModuleSetup2->chnlPairOper = FlexPwmComplementary;
/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule0, &flexPWM0_ModuleSetup0,
&flexPWM0_SignalSetup0);
/* flexPWM0_SignalSetup0_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule0_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule0); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config1' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule1, &flexPWM0_ModuleSetup1,
&flexPWM0_SignalSetup1);
/*flexPWM0_SignalSetup1_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule1_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule1); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config2' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule2, &flexPWM0_ModuleSetup2,
&flexPWM0_SignalSetup2);
/* flexPWM0_SignalSetup2_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule2_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule2); */
}

/* --------- */

/* Make simultaneous changes to HS and LS FET states on submodules0, 1 and 2 of PWM0 */
void HS_LS_action()
{
volatile uint16_t i; /* Make this volatile so compiler doesn't optimise loops out */
/* Modify Channel mode of operation to 'Independent' to allow us to specifiy HS and LS movements using PWM duty */
Modify_PWM_Op_Ind();
/* Start with Both HS and LS off */
Force_HS_LS_Drive(0,0);
/* Turn LS On */
Force_HS_LS_Drive(0,1);
/* Wait for at least 1us - assumes 50ns inst time - ish */
for (i=0, i < 20, i++){
/* Do nothing */
}
/* Then turn LS off again - execution time of function call ensures no overlap, FETS are quick! */
Force_HS_LS_Drive(0,0);
/* Turn HS on */
Force_HS_LS_Drive(1,0);
/* Wait for a minimilast time 100ns plus deadtime is required, so lets say 250ns */
for (i=0, i < 5, i++){
/* Do nothing */
}
/* Turn off HS drive again... and then ready to go immediately without further delay */
Force_HS_LS_Drive(0,0);
/* Put back the original 'Complementary' mode of Channel Operation */
Modify_PWM_Op_Comp();

}

0 Kudos

2,221 Views
mariuslucianand
NXP Employee
NXP Employee

Hello stuart.jobbins@tiscali.co.uk‌,

You can insert the above code either by using the S-function like in this threadAbout Code generation in the Model Based Software  or by inserting some custom code using Simulink Coder like here https://community.nxp.com/message/1040943?commentID=1040943#comment-1040943  

Hope this helps,

Marius

0 Kudos

2,221 Views
stuart_jobbins
Contributor II

OK... i haven't been able to find a simple answer to this... so apologies if it's a dumb question...

Matlab seems to think I need to install another C compiler (when using S-function builder).

Is there any way of convincing Matlab to use the S32DS GCC setup that is part of the MBDT installation, rather than having a different compiler? 

I already have a standalone S32DS installation with another instance of the (same) GCC compiler... but would like to keep the S-function consistent with the rest of the build tools... but I can't see an environment variable that convinces Matlab wher eto find  a compiler (Mex -setup says there isn't one), but the MBDT tools build the model using one!

I don't really want a 3rd instance of a GCC compiler. for the same processor

Regards,

Stuart

0 Kudos

2,221 Views
mariuslucianand
NXP Employee
NXP Employee

Hello stuart.jobbins@tiscali.co.uk‌,

The easiest way would be to install "MATLAB Support for MinGW-w64 C/C++ Compiler" Add on directly in Matlab. I think after that, the comand 'mex - setup' will show you something similar with the following.

>> mex -setup

MEX configured to use 'MinGW64 Compiler (C)' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
variables with more than 2^32-1 elements. You will be required
to update your code to utilize the new API.
You can find more information about this at:
https://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.

To choose a different language, select one from the following:
mex -setup C++
mex -setup FORTRAN

This will help you building that S-function. Matlab will not generate the TPP Code or build it using that MinGW compiler. It will create a mex file behind that S-function block. So I recommend you installing that Add On.

If you really want to try changing the compiler for mex, you can follow the steps from here: Change Default Compiler- MATLAB & Simulink . But first, please have a look on this link Compilers - MATLAB & Simulink.

Hope this Helps,

Marius

0 Kudos

2,221 Views
stuart_jobbins
Contributor II

I gave in last night and installed a 2nd instance of the MinGW compiler to use in Matlab (in addition to the one in eclipse/Cygwin) as well as the 2 compilers for the same target processor for 2 instances of S32DS (one standalone and one embedded in MBDT).

As you can see from the script above, I have a single entry point, single function call with no parameters, but I want to access the data sets and Function calls  (that will exist once the .p scripts have run and created sources, build is built) from the FlexPwm driver set, ideally using all the same definitions (as the build).

SF_Lib_tab.png

The problem I now have is that because of dependencies in the includes, and the S-function wishing to 'build' ahead of the .p scripts running, I cannot apparently satisfy this requirement.... without adding a (pre-built) version of all the dependent sources into my local build directory. 

SF_Output_tab.png

The examples you provide have basic 'standalone' functionality, or simple i/o functionality at the model... but I cant find an example that tries the level of 'symbolic' integration I want to achieve.Can it be done?

I assume I have to have more information declared to the S-Function builder, but its not clear what is needed.. as the S-Function builder appears to try and 'compile' the S-function BEFORE any of the model m scripts(p scripts) run to generate the build C sources.

(I obviously don't have a good mental model of how the libraries section of the S-Function builder is supposed to work!)

Can you point me to any example that does this... or do I just go through and re- define absolutely everything I need locally (in my build directory with a 'local' .h file? 

pwm_mod.c - below

/* GD3000 initialisation ny manipulating FlexPWM configuration temporarily back to independent */
#include "flexpwm_driver.h"
#include <assert.h>
#include <stddef.h>

/* Function to allow us to alter all 3 PWM0 Submodules (0, 1 and 2) corresponding to PhA, B and C, duty cycles */

void Force_HS_LS_Drive(volatile uint16_t DutyA, volatile uint16_t DutyB)
{

FLEXPWM_DRV_UpdatePulseWidth (INST_FLEXPWM0, FlexPwmModule0, DutyA, DutyB, FlexPwmCentreAligned);
FLEXPWM_DRV_LoadCommands(INST_FLEXPWM0, (1 << FlexPwmModule0));
FLEXPWM_DRV_UpdatePulseWidth (INST_FLEXPWM0, FlexPwmModule1, DutyA, DutyB, FlexPwmCentreAligned);
FLEXPWM_DRV_LoadCommands(INST_FLEXPWM0, (1 << FlexPwmModule1));
FLEXPWM_DRV_UpdatePulseWidth (INST_FLEXPWM0, FlexPwmModule2, DutyA, DutyB, FlexPwmCentreAligned);
FLEXPWM_DRV_LoadCommands(INST_FLEXPWM0, (1 << FlexPwmModule2));
}

/* --------- */

/* Modify Channel Mode of Operation to Independent on submodules0, 1 and 2 of PWM0 */
void Modify_PWM_Op_Ind(void)
{
/* Modify the Channel Pair operation and re-init submodule */
flexPWM0_ModuleSetup0->chnlPairOper = FlexPwmIndependent;
flexPWM0_ModuleSetup1->chnlPairOper = FlexPwmIndependent;
flexPWM0_ModuleSetup2->chnlPairOper = FlexPwmIndependent;

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule0, &flexPWM0_ModuleSetup0,
&flexPWM0_SignalSetup0);
/* Ripped out remainder of set-up as shouldn't need to re-assert */

/* flexPWM0_SignalSetup0_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule0_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule0); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config1' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule1, &flexPWM0_ModuleSetup1,
&flexPWM0_SignalSetup1);
/*flexPWM0_SignalSetup1_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule1_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule1); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config2' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule2, &flexPWM0_ModuleSetup2,
&flexPWM0_SignalSetup2);
/* flexPWM0_SignalSetup2_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule2_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule2); */
}

/* --------- */
/* Modify Channel Mode of Operation to Complementary on submodules0, 1 and 2 of PWM0 */
void Modify_PWM_Op_Comp(void)
{
/* Modify the Channel Pair operation back to comlementary and re-init submodule */
flexPWM0_ModuleSetup0->chnlPairOper = FlexPwmComplementary;
flexPWM0_ModuleSetup1->chnlPairOper = FlexPwmComplementary;
flexPWM0_ModuleSetup2->chnlPairOper = FlexPwmComplementary;
/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule0, &flexPWM0_ModuleSetup0,
&flexPWM0_SignalSetup0);
/* flexPWM0_SignalSetup0_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule0_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule0); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config1' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule1, &flexPWM0_ModuleSetup1,
&flexPWM0_SignalSetup1);
/*flexPWM0_SignalSetup1_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule1_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule1); */

/* Start for S-Function (flexpwm_mpc574x_config): '<S2>/FlexPWM_Config2' */

/* Initializing the FLEXPWM0 */
FLEXPWM_DRV_SetupPwm(INST_FLEXPWM0, FlexPwmModule2, &flexPWM0_ModuleSetup2,
&flexPWM0_SignalSetup2);
/* flexPWM0_SignalSetup2_pwm_period_raw_value = 4000U;
PINS_DRV_Init(2U, pwm0_submodule2_pin_config); */

/* Counter start FLEXPWM0 */
/* FLEXPWM_DRV_CounterStart(INST_FLEXPWM0, FlexPwmModule2); */
}

/* Make simultaneous changes to HS and LS FET states on submodules0, 1 and 2 of PWM0 */
void HS_LS_action(void)
{
volatile uint16_t i; /* Make this volatile so compiler doesn't optimise loops out */
/* Modify Channel mode of operation to 'Independent' to allow us to specifiy HS and LS movements using PWM duty */
Modify_PWM_Op_Ind();
/* Start with Both HS and LS off */
Force_HS_LS_Drive(0,0);
for (i=0, i < 50, i++){
/* Do nothing for approx 2.5us */
}
/* Turn LS On */
Force_HS_LS_Drive(0,1);
/* Wait for at least 1us - assumes 50ns inst time - ish */
for (i=0, i < 20, i++){
/* Do nothing */
}
/* Then turn LS off again - execution time of function call ensures no overlap, FETS are quick! */
Force_HS_LS_Drive(0,0);
for (i=0, i < 50, i++){
/* Do nothing for approx 2.5us */
}
/* Turn HS on */
Force_HS_LS_Drive(1,0);
/* Wait for a minimilast time 100ns plus deadtime is required, so lets say 250ns */
for (i=0, i < 5, i++){
/* Do nothing */
}
/* Turn off HS drive again... and then ready to go immediately without further delay */
Force_HS_LS_Drive(0,0);
for (i=0, i < 50, i++){
/* Do nothing for approx 2.5us */
}
/* Put back the original 'Complementary' mode of Channel Operation */
Modify_PWM_Op_Comp();

}

Basically I want to re-use the FlexPWM driver data structure and function calls (which should be 'public' by virtue of the FlexPWM_driver.h)... but it doesn't exist when I have to tell the S-Function builder to build. If I copy (a previously produced FlexPWM_driver .c/.h) into my local build directory.. it then complains about other dependencies... and so on... as I drag in more and more previously built .c/.h sources to my local build directory.

Any pointers on how to call C-functions (that exist outside my local source/build directory) would be appreciated.

Regards,

Stuart

0 Kudos

2,221 Views
stuart_jobbins
Contributor II

Marius, Adrian,

I have looked at the suggested material, but its clear that these abilities only relate to 'Masking' the outputs in order to synchronise them, not control the output state (other than off).

In order to meet the GD3000 initialisation sequence I need to take control of the 'state' of the HS and LS driver pins, independently, to go through the HS and LS toggles (which the examples in the NXP MBDT Toolbox for both PMSM Open and Closed Loop do not respect because they only have a single output).

In fact, when I looked at the BLDC models for the independent PWM output drives, the GD3000 initialisation sequence is also not respected (fails to toggle HS drives), but at least there is the ability to alter the sequence (at the model level) to man-handle the HS and LS toggles according to the spec requirements for initialisation.

So my choices now seem to rely on writing a function that can toggle the PWM HS and LS outputs, but the final configuration I need to operate in is 'complementary' to use the SVM library.. so it is unclear (from the Programmers Reference Manual) whether I can:

i) Statically configure the MPC5744P as complementary from within the Model and then override some settings in my function to force the output states (of HS and LS independently) to satisfy the GD3000, and revert them afterwards

ii) Statically configure HS and LS pins as GPIO to force the appropriate pins (that will be eventually muxed as PWM outputs) and then provide a function that forces the PWMs into complementary mode (but not clear what the Model interface becomes in this case - as I want to use the PWM duty cycle from the SVM library function)

If I use strategy i) is the best option to temporarily try and reconfigure the output pins as GPIO and bit bash?, or to configure as independent PWM and force 100%/0% duty waveforms as appropriate to force the outputs, then revert back to complementary mode?

The PRM is unclear about the consequences of dynamically changing the MUXing of signals, let alone the consequences of changing the source configuration dynamically.

P.S. I can't believe nobody else has ever attempted to use the MBDT examples for a PMSM (BLAC) motor configuration and not noticed the GD3000 FET driver output start-up reaction is undefined (frequently large currents, crow-bar across supply due to HS FETs being sometimes on whilst LS becomes active), because the initialisation is not respected. 

Many thanks for your continued support,

Stuart

0 Kudos

2,221 Views
richard_king
Contributor I

Hi Stuart,

I designed a high current driver board using the MC33GD3000 and MPC5744P and experienced the same problem you've reported. The BLDC demos worked fine on my board although the recommended MC33GD3000 initialisation didn't appear to be followed by the examples. If I try running either of the PMSM examples the inverter basically shorts the input supply which I believe is caused by incorrect initialisation of the MC33GD3000.

I was unable to resolve this within the MBDT and resorted to modifying the C source generated by the Matlab toolchain as a temporary workaround.

Best regards
Richard

0 Kudos

2,220 Views
mariuslucianand
NXP Employee
NXP Employee

Hello stuart.jobbins@tiscali.co.uk‌,

You are right, we do not support changing dynamically the PWM output mode for example from independent to complementary. In our examples we use independent mode, this being the reason why the GD3000 init works. 

But, I think you can obtain the desired functionality (complementary mode and still init correctly the GD3000) by inserting some custom code. You can use the S32SDK driver function FLEXPWM_DRV_MaskOutput or FLEXPWM_DRV_ForceApplyMask to mask the outputs and then by writing to the Output Control Register you can obtain the desired output states on PWM pins. This is valid for the MPC57xx toolbox which I think you are using (from previous discussion). 

On the latest S32K1xx toolbox we have added a TPP Driver Blocks (to support GD3000 driver initialization sequence).

Hope this helps,

Marius

0 Kudos

2,223 Views
stuart_jobbins
Contributor II

Hi Marius,

You are correct, I am using the MPC57xx toolbox on a setup that is an MPC5744P and GD Devkit inverter board.

The NXP MBDT examples (PMSM, not BLDC) both use Complementary Mode as their static initialisation of PWM outputs and claim to be tested on GD Devkit which has GD3000 chip.

Happy to write some custom code... but where do I find documentation (and sources) on the S32SDK drivers, specifically the FLEXPWM_DRVMaskOutput and FLEXPWM_DRV_ForceApplyMask?

What is a TPP Driver Block? (and would it be easier for me to port this to MPC57xx toolbox?)

Regards

Stuart

0 Kudos

2,225 Views
adriantudor
NXP Employee
NXP Employee

Hi Stuart,

The MPC57xx toolbox is based on S32K SDK for Power Architecture RTM2.0.0 which can be found here. You can find documentation in this archive.

We have added support in MBDT for S32K1xx for Motor and solenoid driver (TPP --> Three Phase PreDriver): MC33GD3000, MC34GD3000, MC33937 and MC34937. For more detail please check this.

Those TPP blocks are used to initialize, configure, handle interrupt of any IC supported.

 

You can't port any of those TPP driver blocks (due to additional peripheric blocks needed) to  MPC57xx toolbox, but you can try to use this official driver by using custom code.

Best Regards,

Adrian