This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MOTORWARE: Recommended method of structuring multiple projects

Part Number: MOTORWARE

Tool/software: Code Composer Studio

My department is in the process of attempting to move over to the InstaSpin platform from other manufacturers and are having trouble deciding how we would like to structure our "core" project so that it closely mirrors MotorWare but is relatively 'self-contained'.

On other platforms, we have had our own libraries for drivers, modules, and other software that have been 100% internally controlled.  We can save source code and library files into a Git repository and easily revision, diff, check-in and check-out branches.  This makes source control very simple and the method translates to multiple projects with the same code base.

Up to this point, it looks like we are going to have two types of projects:

  • 'characterization' project which will be used to identify and characterize motors, based on lab02b
  • 'project template', with each project having its own 'custom' files for using different A/Ds, adding custom software, etc.

Using lab02b for characterization is really no big deal.  It is sort of made for that anyway and any customization made within the defined lab02b workflow will work.  Each project will have its own 'main.c', 'user.h', 'hal.c', and 'hal.h' along with a couple of other files.  This project load will likely be based on lab03, but cannot be created using the lab-defined workflow without breaking source control methods.

After all that, my question: What is the TI recommended method for using MotorWare-derived projects while also taking advantage of source control methodologies and allowing each project to stand on its own by having all that it needs within the same file set?  I have looked around quite a bit on the forums and I have found that most questions are InstaSpin-related rather than source-control related and simply haven't been able to find any guidance in this area.

  • Please help me better understand your question so I can help guide you here. You would like to have "stand-alone" file directories/structures that can run MW projects, and then revision control these using something like BitBucket?

    Sean
  • Yes, revision control using bitbucket is exactly the type of workflow that I'm looking for.
  • From what I've read, here is what I think you are asking for.

    For a "project template," you'll want to decide whether or not you're looking for InstaSPIN projects that use or do not use the controller module (CTRL). If you are not looking for the CTRL state machine and would rather implement one yourself, I would start with lab11a, which is a feature-rich lab without the controller module. Otherwise, if you're looking to use the CTRL module, I would start with either lab5a if you're interested in torque control, or 5b if you're interested in speed control.

    To make a stand-alone directory, all you'll have to do is recreate the include paths and linked resource paths in a local folder. You can select "Copy projects into workspace" to move the source into your local workspace directory. Once you have a project template and a localized version, I would commit this as v0 of your template to whichever repository you're working with. Each time you want to add a new InstaSPIN feature, such as overmodulation or online Rs recalc, you should commit again.

    From our side, our releases are partitioned into two BitBucket repositores - Motorware, which is the whole release as downloadable by you, and drivers, which is a sub-repository that we use to revision control only the drivers folder, which pertains to our MCU modules.

    I'm not sure if this was the type of response you were looking for. I would be happy to elaborate more on how I personally ensure proper version control if needed.

    Sean
  • Sean, 

    As you mentioned lab11a didn't have the state machine, so i want to add the state machine in the background loop.

    But I'm wondering how you control the timing for each state in the background loop? I'll assume the sate machine should add in the for(;;) loop, but in that case, the ISR can interrupt at any time that means we can't control the timing precisely. Is that true ? 

    Is there any suggestion about how I can add the state machine in the lab11a project ?

    YZ

  • YZ,

    I would recommend using a lab that has the CTRL structure implemented, as that is the state machine I was referring to. Lab11/11a are the labs with it removed, starting from lab10 backwards should show the the CTRL state machine is implemented, and how state transitions take place.

    Sean
  • Sean, 

    Thanks for the reply.

    1) Let's we use lab10a that has CTRL structure. One of the function related to state machine is bool CTRL_updateState(CTRL_Handle handle). But I'm not sure how the timing is controlled in each state?

    It use condition ( counter_ctrlState >= waitTime) for the state transient, but when we trace back the waitTime, it is assigned to 0 in user.h .

    pUserParams->ctrlWaitTime[CTRL_State_Error] = 0;
    pUserParams->ctrlWaitTime[CTRL_State_Idle] = 0;
    pUserParams->ctrlWaitTime[CTRL_State_OffLine] = (uint_least32_t)( 5.0 * USER_CTRL_FREQ_Hz);
    pUserParams->ctrlWaitTime[CTRL_State_OnLine] = 0;

    So basically there is no timing control for each state. Can I understand it's more like an if-else forever loop for each state transition ? Like if we run into any fault situation, it'll goes to the fault state; if there's no fault, like normal operation, it'll just transient into Idle, Online state etc. ?

    2) My confusion is that this state machine runs in the background loop, however, the mainISR can interrupt at any time and at any state transition. So it's hard to say how long it'll take for the minimum time for each state. If we have an operating system, we could easily control the timing by define the time slice in a pre-emptive multitasking operating system , which in terms it is our minimum on time for the each state. For the DSP without operating system, are we able to precisely define the timing using CTRL structure ?

    bool CTRL_updateState(CTRL_Handle handle)
    {
    CTRL_State_e ctrlState = CTRL_getState(handle);
    bool flag_enableCtrl = CTRL_getFlag_enableCtrl(handle);
    bool stateChanged = false;


    if(flag_enableCtrl)
    {
    uint_least32_t waitTime = CTRL_getWaitTime(handle,ctrlState);
    uint_least32_t counter_ctrlState = CTRL_getCount_state(handle);


    // check for errors
    CTRL_checkForErrors(handle);


    if(counter_ctrlState >= waitTime)
    {
    // reset the counter
    CTRL_resetCounter_state(handle);


    if(ctrlState == CTRL_State_OnLine)
    {
    CTRL_Obj *obj = (CTRL_Obj *)handle;
    _iq Id_target = TRAJ_getTargetValue(obj->trajHandle_Id);

    // update the estimator state
    bool flag_estStateChanged = EST_updateState(obj->estHandle,Id_target);

    if(flag_estStateChanged)
    {
    // setup the controller
    CTRL_setupCtrl(handle);

    // setup the trajectory
    CTRL_setupTraj(handle);
    }

    if(EST_isOnLine(obj->estHandle))
    {
    // setup the estimator for online state
    CTRL_setupEstOnLineState(handle);
    }

    if(EST_isLockRotor(obj->estHandle) ||
    (EST_isIdle(obj->estHandle) && EST_isMotorIdentified(obj->estHandle)))
    {
    // set the enable controller flag to false
    CTRL_setFlag_enableCtrl(handle,false);

    // set the next controller state
    CTRL_setState(handle,CTRL_State_Idle);
    }
    }
    else if(ctrlState == CTRL_State_OffLine)
    {
    // set the next controller state
    CTRL_setState(handle,CTRL_State_OnLine);
    }
    else if(ctrlState == CTRL_State_Idle)
    {
    CTRL_Obj *obj = (CTRL_Obj *)handle;
    bool flag_enableUserMotorParams = CTRL_getFlag_enableUserMotorParams(handle);

    if(flag_enableUserMotorParams)
    {
    // initialize the motor parameters using values from the user.h file
    CTRL_setUserMotorParams(handle);
    }

    if(EST_isIdle(obj->estHandle))
    {
    // setup the estimator for idle state
    CTRL_setupEstIdleState(handle);

    if(EST_isMotorIdentified(obj->estHandle))
    {
    if(CTRL_getFlag_enableOffset(handle))
    {
    // set the next controller state
    CTRL_setState(handle,CTRL_State_OffLine);
    }
    else
    {
    // set the next controller state
    CTRL_setState(handle,CTRL_State_OnLine);
    }
    }
    else
    {
    // set the next controller state
    CTRL_setState(handle,CTRL_State_OffLine);
    }
    }
    else if(EST_isLockRotor(obj->estHandle))
    {
    // set the next controller state
    CTRL_setState(handle,CTRL_State_OnLine);
    }
    }
    } // if(counter_ctrlState >= waitTime) loop