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.

TMS320F28027F: TMS320F28027with DRV8301 to run bldc motor

Part Number: TMS320F28027F
Other Parts Discussed in Thread: MOTORWARE, C2000WARE, TIDA-010265

Tool/software:

I am using the Lab2b example to add UART commands for controlling a motor. Specifically, I am implementing commands such as Rx_on to start the motor and Rx_off to stop it. I am following the HAL tutorials in Motorware for this implementation. I have added SCI functions to taken in the HAL tutorials in Motorware. The relevant files are hal.c, hal.h, and pie.c, are added or write some functions for sci which are provided below. 

5344.hal.h

/cfs-file/__key/communityserver-discussions-components-files/171/7142.pie.c

Any modifies in files. Please help me anyone and also guide me. In above files any mistakes are there please modify and resend it.

  • Hello Kishor,

    One of the code files you posted caused an issue with our E2E system which lead to this post going unnoticed until today. I've removed that file and attached the other two as file attachments on the thread. Please see if you can upload the other code file as just a file only.

    One of our experts will review this thread shortly.

    Best Regards,

    Ralph Jacobi

  • Hello,

    Your post does not clarify what issues you are facing. Without that information, I'm unable to assist you directly.

    However, I do know of a problem I've been informed of recently with the 'motorware_hal_tutorial.pdf' document section '6.7. Adding SCI/UART functionality to a Motorware project'. If you were not aware of this tutorial, it is available in MotorWare and does exactly what you're looking for.

    If you were already aware of that tutorial and/or you were not able to get that tutorial to work, refer to the motor1_ISR() function and find this line:

    • Follow the function definition to hal_2motors.h
    • Based on the instructions in the SCI/UART functionality tutorial:
      • PIE_clearInt(-); needs to be changed to PIE_clearInt(obj->pieHandle,PIE_GroupNumber_1);

    Regards,
    Jason Osborn

  • Hi Jason Osborn

    I added SCI RX function  in main.c file. I have attached below.

    // system includes
    #include <math.h>
    #include "main.h"
    
    #include "sw/drivers/sci/src/32b/f28x/f2802x/sci.h"
    #include "hal.h"
    #include "hal_obj.h"
    
    
    #ifdef FLASH
    #pragma CODE_SECTION(mainISR,"ramfuncs");
    #endif
    
    // Include header files used in the main function
    
    
    // **************************************************************************
    // the defines
    
    #define LED_BLINK_FREQ_Hz   5
    
    
    // **************************************************************************
    // the globals
    
    uint_least16_t gCounter_updateGlobals = 0;
    
    bool Flag_Latch_softwareUpdate = true;
    
    CTRL_Handle ctrlHandle;
    
    #ifdef CSM_ENABLE
    #pragma DATA_SECTION(halHandle,"rom_accessed_data");
    #endif
    HAL_Handle halHandle;
    
    #ifdef CSM_ENABLE
    #pragma DATA_SECTION(gUserParams,"rom_accessed_data");
    #endif
    USER_Params gUserParams;
    
    HAL_PwmData_t gPwmData = {_IQ(0.0), _IQ(0.0), _IQ(0.0)};
    
    HAL_AdcData_t gAdcData;
    
    _iq gMaxCurrentSlope = _IQ(0.0);
    
    #ifdef FAST_ROM_V1p6
    CTRL_Obj *controller_obj;
    #else
    
    #ifdef CSM_ENABLE
    #pragma DATA_SECTION(ctrl,"rom_accessed_data");
    #endif
    
    CTRL_Obj ctrl;              //v1p7 format
    #endif
    
    uint16_t gLEDcnt = 0;
    
    volatile MOTOR_Vars_t gMotorVars = MOTOR_Vars_INIT;
    
    #ifdef FLASH
    // Used for running BackGround in flash, and ISR in RAM
    extern uint16_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
    
    #ifdef F2802xF
    extern uint16_t *econst_start, *econst_end, *econst_ram_load;
    extern uint16_t *switch_start, *switch_end, *switch_ram_load;
    #endif
    #endif
    
    
    #ifdef DRV8301_SPI
    // Watch window interface to the 8301 SPI
    DRV_SPI_8301_Vars_t gDrvSpi8301Vars;
    #endif
    
    #ifdef DRV8305_SPI
    // Watch window interface to the 8305 SPI
    DRV_SPI_8305_Vars_t gDrvSpi8305Vars;
    #endif
    
    // **************************************************************************
    // the functions
    
    //Added
    // Define motor control and UART variables
    bool isMotorOn = false;
    bool isWaitingTxFifoEmpty = false;
    bool isTxOffDelayActive = false;
    int txOffDelayCounter = 0;
    int txOffDelayCount = 1000;  // Example delay count
    int counter = 0;
    char buf[8];
    char returnBuf[8];
    
    HAL_Obj *halHandle;
    
    // UART Command Definitions
    /*#define CMD_RX_ON  "RX_ON"
    #define CMD_RX_OFF "RX_OFF"*/
    
    
    
    // Added
    
    uint16_t boardId = '5';
    
    volatile bool isVoltageTooLow = true;
    _iq lowVoltageThreshold = _IQ(0.01);
    
    bool isCommandReceived = false;
    bool isCommandStart = false;
    bool isOpenLoop = false;
    bool shouldSendSpeed = false;
    
    
    // Constants for command processing
    #define BUF_SIZE 8
    #define CMD_RX_ON "RX_ON"
    #define CMD_RX_OFF "RX_OFF"
    
    
    // Globals for UART and motor control
    static char buf[BUF_SIZE];
    //static int counter = 0;
    //static bool isMotorOn = false;
    
    
    
    void main(void)
    {
      uint_least8_t estNumber = 0;
    
    
    #ifdef FAST_ROM_V1p6
      uint_least8_t ctrlNumber = 0;
    #endif
    
      // Only used if running from FLASH
      // Note that the variable FLASH is defined by the project
      #ifdef FLASH
      // Copy time critical code and Flash setup code to RAM
      // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
      // symbols are created by the linker. Refer to the linker files.
      memCopy((uint16_t *)&RamfuncsLoadStart,(uint16_t *)&RamfuncsLoadEnd,(uint16_t *)&RamfuncsRunStart);
    
      #ifdef CSM_ENABLE
        //copy .econst to unsecure RAM
        if(*econst_end - *econst_start)
          {
            memCopy((uint16_t *)&econst_start,(uint16_t *)&econst_end,(uint16_t *)&econst_ram_load);
          }
    
        //copy .switch ot unsecure RAM
        if(*switch_end - *switch_start)
          {
            memCopy((uint16_t *)&switch_start,(uint16_t *)&switch_end,(uint16_t *)&switch_ram_load);
          }
      #endif
      #endif
    
      // initialize the hardware abstraction layer
      halHandle = HAL_init(&hal,sizeof(hal));
    
    
      // check for errors in user parameters
      USER_checkForErrors(&gUserParams);
    
    
      // store user parameter error in global variable
      gMotorVars.UserErrorCode = USER_getErrorCode(&gUserParams);
    
    
      // do not allow code execution if there is a user parameter error
      if(gMotorVars.UserErrorCode != USER_ErrorCode_NoError)
        {
          for(;;)
            {
              gMotorVars.Flag_enableSys = false;
            }
        }
    
    
      // initialize the user parameters
      USER_setParams(&gUserParams);
    
    
      // set the hardware abstraction layer parameters
      HAL_setParams(halHandle,&gUserParams);
    
    
      // initialize the controller
    #ifdef FAST_ROM_V1p6
      ctrlHandle = CTRL_initCtrl(ctrlNumber, estNumber);        //v1p6 format (06xF and 06xM devices)
      controller_obj = (CTRL_Obj *)ctrlHandle;
    #else
      ctrlHandle = CTRL_initCtrl(estNumber,&ctrl,sizeof(ctrl)); //v1p7 format default
    #endif
    
    
      {
        CTRL_Version version;
    
        // get the version number
        CTRL_getVersion(ctrlHandle,&version);
    
        gMotorVars.CtrlVersion = version;
      }
    
    
      // set the default controller parameters
      CTRL_setParams(ctrlHandle,&gUserParams);
    
    
      // setup faults
      HAL_setupFaults(halHandle);
    
    
      // initialize the interrupt vector table
      HAL_initIntVectorTable(halHandle);
    
    
      // enable the ADC interrupts
      HAL_enableAdcInts(halHandle);
    
    
      //Added
    
      // enable the SCI interrupts
        HAL_enableSciInts(halHandle);
    
    
    
      // enable global interrupts
      HAL_enableGlobalInts(halHandle);
    
    
      // enable debug interrupts
      HAL_enableDebugInt(halHandle);
    
    
      // disable the PWM
      HAL_disablePwm(halHandle);
    
    
    #ifdef DRV8301_SPI
      // turn on the DRV8301 if present
      HAL_enableDrv(halHandle);
      // initialize the DRV8301 interface
      HAL_setupDrvSpi(halHandle,&gDrvSpi8301Vars);
    #endif
    
    #ifdef DRV8305_SPI
      // turn on the DRV8305 if present
      HAL_enableDrv(halHandle);
      // initialize the DRV8305 interface
      HAL_setupDrvSpi(halHandle,&gDrvSpi8305Vars);
    #endif
    
    
      // enable DC bus compensation
      CTRL_setFlag_enableDcBusComp(ctrlHandle, true);
    
    
      for(;;)
      {
        // Waiting for enable system flag to be set
        while(!(gMotorVars.Flag_enableSys));
    
        // loop while the enable system flag is true
        while(gMotorVars.Flag_enableSys)
          {
    
     //Added
           /* if (counter == 8) {
                            isCommandReceived = false;
    
                            if (buf[1] == boardId && buf[2] == 's') {
                                long value = ((long)buf[3]) | ((long)buf[4] << 8) | ((long)buf[5] << 16) | ((long)buf[6] << 24);
                                bool isRunIdentify = true;
    
                                if (value == _IQ(0.0)) {
                                    isRunIdentify = 0;
                                } else if (_IQabs(value) <= _IQ(0.2)) {
                                    isOpenLoop = true;
                                } else {
                                    isOpenLoop = false;
                                }
    
                                gMotorVars.SpeedRef_krpm = value;
                                gMotorVars.Flag_Run_Identify = isRunIdentify;
                            }
    
                            isCommandStart = false;
                            counter = 0;
                        }
    
                        if (shouldSendSpeed) {
                            shouldSendSpeed = false;
    
                            if (buf[1] == boardId && buf[2] == 's') {
                                returnBuf[0] = '<';
                                returnBuf[1] = boardId;
                                returnBuf[2] = 'd';
    
                                long returnValue = gMotorVars.Speed_krpm;
    
                                returnBuf[3] = returnValue;
                                returnBuf[4] = returnValue >> 8;
                                returnBuf[5] = returnValue >> 16;
                                returnBuf[6] = returnValue >> 24;
                                returnBuf[7] = '>';
    
                                serialWrite(returnBuf, 8);
                            }
                        }*/
    
    
    
    
            CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle;
    
            // increment counters
            gCounter_updateGlobals++;
    
    
            if(CTRL_isError(ctrlHandle))
              {
                // set the enable controller flag to false
                CTRL_setFlag_enableCtrl(ctrlHandle,false);
    
                // set the enable system flag to false
                gMotorVars.Flag_enableSys = false;
    
                // disable the PWM
                HAL_disablePwm(halHandle);
              }
            else
              {
                // update the controller state
                bool flag_ctrlStateChanged = CTRL_updateState(ctrlHandle);
    
                // enable or disable the control
                CTRL_setFlag_enableCtrl(ctrlHandle, gMotorVars.Flag_Run_Identify);
    
                if(flag_ctrlStateChanged)
                  {
                    CTRL_State_e ctrlState = CTRL_getState(ctrlHandle);
                    EST_State_e estState = EST_getState(obj->estHandle);
    
                    if(ctrlState == CTRL_State_OffLine)
                      {
                        // enable the PWM
                        HAL_enablePwm(halHandle);
                      }
                    else if(ctrlState == CTRL_State_OnLine)
                      {
                        if((estState < EST_State_LockRotor) || (estState > EST_State_MotorIdentified))
                          {
                            // update the ADC bias values
                            HAL_updateAdcBias(halHandle);
                          }
    
                        // Return the bias value for currents
                        gMotorVars.I_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Current,0);
                        gMotorVars.I_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Current,1);
                        gMotorVars.I_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Current,2);
    
                        // Return the bias value for voltages
                        gMotorVars.V_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Voltage,0);
                        gMotorVars.V_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Voltage,1);
                        gMotorVars.V_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Voltage,2);
    
                        // enable the PWM
                        HAL_enablePwm(halHandle);
                      }
                    else if(ctrlState == CTRL_State_Idle)
                      {
                        // disable the PWM
                        HAL_disablePwm(halHandle);
                        gMotorVars.Flag_Run_Identify = false;
                      }
    
                    if((CTRL_getFlag_enableUserMotorParams(ctrlHandle) == true) &&
                      (ctrlState > CTRL_State_Idle) &&
                      (gMotorVars.CtrlVersion.minor == 6))
                      {
                        // call this function to fix 1p6
                        USER_softwareUpdate1p6(ctrlHandle);
                      }
    
                  }
              }
    
    
            if(EST_isMotorIdentified(obj->estHandle))
              {
                // set the current ramp
                EST_setMaxCurrentSlope_pu(obj->estHandle,gMaxCurrentSlope);
                gMotorVars.Flag_MotorIdentified = true;
    
                // set the speed reference
                CTRL_setSpd_ref_krpm(ctrlHandle,gMotorVars.SpeedRef_krpm);
    
                // set the speed acceleration
                CTRL_setMaxAccel_pu(ctrlHandle,_IQmpy(MAX_ACCEL_KRPMPS_SF,gMotorVars.MaxAccel_krpmps));
    
                if(Flag_Latch_softwareUpdate)
                {
                  Flag_Latch_softwareUpdate = false;
    
                  USER_calcPIgains(ctrlHandle);
                }
    
              }
            else
              {
                Flag_Latch_softwareUpdate = true;
    
                // the estimator sets the maximum current slope during identification
                gMaxCurrentSlope = EST_getMaxCurrentSlope_pu(obj->estHandle);
              }
    
    
            // when appropriate, update the global variables
            if(gCounter_updateGlobals >= NUM_MAIN_TICKS_FOR_GLOBAL_VARIABLE_UPDATE)
              {
                // reset the counter
                gCounter_updateGlobals = 0;
    
                updateGlobalVariables_motor(ctrlHandle);
              }
    
            // recalculate Kp and Ki gains to fix the R/L limitation of 2000.0, and Kp limit to 0.11
            recalcKpKi(ctrlHandle);
    
            if(CTRL_getMotorType(ctrlHandle) == MOTOR_Type_Induction)
              {
                // set electrical frequency limit to zero while identifying an induction motor
                setFeLimitZero(ctrlHandle);
    
                // calculate Dir_qFmt for acim motors
                acim_Dir_qFmtCalc(ctrlHandle);
              }
    
            // enable/disable the forced angle
            EST_setFlag_enableForceAngle(obj->estHandle,gMotorVars.Flag_enableForceAngle);
    
            // enable or disable power warp
            CTRL_setFlag_enablePowerWarp(ctrlHandle,gMotorVars.Flag_enablePowerWarp);
    
    #ifdef DRV8301_SPI
            HAL_writeDrvData(halHandle,&gDrvSpi8301Vars);
    
            HAL_readDrvData(halHandle,&gDrvSpi8301Vars);
    #endif
    #ifdef DRV8305_SPI
            HAL_writeDrvData(halHandle,&gDrvSpi8305Vars);
    
            HAL_readDrvData(halHandle,&gDrvSpi8305Vars);
    #endif
          } // end of while(gFlag_enableSys) loop
    
    
        // disable the PWM
        HAL_disablePwm(halHandle);
    
        // set the default controller parameters (Reset the control to re-identify the motor)
        CTRL_setParams(ctrlHandle,&gUserParams);
        gMotorVars.Flag_Run_Identify = false;
    
      } // end of for(;;) loop
    
    } // end of main() function
    
    
    interrupt void mainISR(void)
    {
      // toggle status LED
      if(++gLEDcnt >= (uint_least32_t)(USER_ISR_FREQ_Hz / LED_BLINK_FREQ_Hz))
      {
        HAL_toggleLed(halHandle,(GPIO_Number_e)HAL_Gpio_LED2);
        gLEDcnt = 0;
      }
    
    
      // acknowledge the ADC interrupt
      HAL_acqAdcInt(halHandle,ADC_IntNumber_1);
    
    
      // convert the ADC data
      HAL_readAdcData(halHandle,&gAdcData);
    
    
      // run the controller
      CTRL_run(ctrlHandle,halHandle,&gAdcData,&gPwmData);
    
    
      // write the PWM compare values
      HAL_writePwmData(halHandle,&gPwmData);
    
    
      // setup the controller
      CTRL_setup(ctrlHandle);
    
    
     //Added
    
    
    
     /* if (isWaitingTxFifoEmpty)
        {
          if (SCI_txFifoIsEmpty(halHandle->sciAHandle)) {
             // if (isWaitingTxFifoEmpty(halHandle->sciAHandle)) {
    
            if (isTxOffDelayActive) {
              txOffDelayCounter++;
              if (txOffDelayCounter >= txOffDelayCount) {
                isTxOffDelayActive = false;
                txOffDelayCounter = 0;
                isWaitingTxFifoEmpty = false;
              }
            } else {
              isWaitingTxFifoEmpty = false;
            }
          }
        }*/
    
      return;
    } // end of mainISR() function
    
    
    //Added
    
    // SCI Rx ISR
    /*interrupt void sciARxISR(void)
    {
      HAL_Obj *obj = (HAL_Obj *)halHandle;
    
      while (SCI_rxDataReady(obj->sciAHandle))
      {
        char c = SCI_read(obj->sciAHandle);
    
        // Process received characters
        if (counter < 8)
        {
          if (counter == 0)
          {
            if (c == '<')
            {
              buf[counter] = c;
              counter++;
            }
          }
          else if (counter < 7)
          {
            buf[counter] = c;
            counter++;
          }
          else if (counter == 7)
          {
            if (c == '>')
            {
              buf[counter] = c;
              counter++;
              buf[counter] = '\0'; // Null-terminate the command string
    
              // Process the received command
              if (strcmp(buf, CMD_RX_ON) == 0)
              {
                isMotorOn = true;
                sendResponse("Motor ON");
              }
              else if (strcmp(buf, CMD_RX_OFF) == 0)
              {
                isMotorOn = false;
                sendResponse("Motor OFF");
              }
            }
            else
            {
              counter = 0;
            }
          }
        }
      }
    
      // Clear SCI interrupt flag
      PIE_clearInt(obj->pieHandle, PIE_GroupNumber_9);
    }
    
    // Send response to UART
    void sendResponse(char *message)
    {
      int length = strlen(message);
      returnBuf[0] = '<';
      strncpy(&returnBuf[1], message, length);
      returnBuf[length + 1] = '>';
      serialWrite(returnBuf, length + 2);
    }
    
    // Write data to UART
    void serialWrite(char *sendData, int length)
    {
      int i = 0;
      while (i < length)
      {
        if (SCI_txReady(halHandle->sciAHandle))
        {
          SCI_write(halHandle->sciAHandle, sendData[i]);
          i++;
        }
      }
      isWaitingTxFifoEmpty = true;
    }*/
    
    
    //Added
    
    /*static void processCommand(char *buf) {
        if (strcmp(buf, CMD_RX_ON) == 0) {
            isMotorOn = true;
            sendResponse("Motor ON");
        } else if (strcmp(buf, CMD_RX_OFF) == 0) {
            isMotorOn = false;
            sendResponse("Motor OFF");
        } else {
            sendResponse("Unknown Command");
        }
    }
    
    interrupt void sciARxISR(void) {
        HAL_Obj *obj = (HAL_Obj *)halHandle;
        static char buf[BUF_SIZE];
        static int counter = 0;
    
        while (SCI_rxDataReady(obj->sciAHandle)) {
            char c = SCI_read(obj->sciAHandle);
    
            if (counter < BUF_SIZE) {
                buf[counter++] = c;
                if (counter == BUF_SIZE && buf[BUF_SIZE - 1] == '>') {
                    buf[counter] = '\0'; // Null-terminate the command string
                    processCommand(buf);
                    counter = 0; // Reset buffer index
                }
            } else {
                counter = 0; // Reset on overflow
            }
        }
    
        // Clear SCI interrupt flag
        PIE_clearInt(obj->pieHandle, PIE_GroupNumber_9);
    }*/
    
    
    
    
    // UART Rx ISR
    interrupt void sciARxISR(void)
    {
        HAL_Obj *obj = (HAL_Obj *)halHandle;
    
        while (SCI_rxDataReady(obj->sciAHandle))
        {
            char c = SCI_read(obj->sciAHandle);
    
            if (counter < BUF_SIZE - 1) // -1 to leave space for null terminator
            {
                buf[counter++] = c;
    
                if (c == '>') // End of command
                {
                    buf[counter] = '\0'; // Null-terminate the command string
                    processCommand(buf);
                    counter = 0; // Reset buffer index
                }
            }
            else
            {
                // Buffer overflow, reset counter
                counter = 0;
            }
        }
    
        // Clear SCI interrupt flag
        PIE_clearInt(obj->pieHandle, PIE_GroupNumber_9);
    }
    
    // Process received command
    void processCommand(char *command)
    {
        if (strcmp(command, CMD_RX_ON) == 0)
        {
            isMotorOn = true;
            sendResponse("Motor ON");
        }
        else if (strcmp(command, CMD_RX_OFF) == 0)
        {
            isMotorOn = false;
            sendResponse("Motor OFF");
        }
        else
        {
            sendResponse("Unknown Command");
        }
    }
    
    // Send response to UART
    void sendResponse(const char *message)
    {
        int length = strlen(message);
        returnBuf[0] = '<';
        strncpy(&returnBuf[1], message, length);
        returnBuf[length + 1] = '>';
        serialWrite(returnBuf, length + 2);
    }
    
    // Write data to UART
    void serialWrite(const char *sendData, int length)
    {
        int i = 0;
        while (i < length)
        {
            if (SCI_txReady(halHandle->sciAHandle))
            {
                SCI_write(halHandle->sciAHandle, sendData[i]);
                i++;
            }
        }
        isWaitingTxFifoEmpty = true;
    }
    
    
    
    
    void updateGlobalVariables_motor(CTRL_Handle handle)
    {
      CTRL_Obj *obj = (CTRL_Obj *)handle;
    
      // get the speed estimate
      gMotorVars.Speed_krpm = EST_getSpeed_krpm(obj->estHandle);
    
      // get the real time speed reference coming out of the speed trajectory generator
      gMotorVars.SpeedTraj_krpm = _IQmpy(CTRL_getSpd_int_ref_pu(handle),EST_get_pu_to_krpm_sf(obj->estHandle));
    
      // get the magnetizing current
      gMotorVars.MagnCurr_A = EST_getIdRated(obj->estHandle);
    
      // get the rotor resistance
      gMotorVars.Rr_Ohm = EST_getRr_Ohm(obj->estHandle);
    
      // get the stator resistance
      gMotorVars.Rs_Ohm = EST_getRs_Ohm(obj->estHandle);
    
      // get the stator inductance in the direct coordinate direction
      gMotorVars.Lsd_H = EST_getLs_d_H(obj->estHandle);
    
      // get the stator inductance in the quadrature coordinate direction
      gMotorVars.Lsq_H = EST_getLs_q_H(obj->estHandle);
    
      // get the flux
      gMotorVars.Flux_VpHz = EST_getFlux_VpHz(obj->estHandle);
    
      // get the controller state
      gMotorVars.CtrlState = CTRL_getState(handle);
    
      // get the estimator state
      gMotorVars.EstState = EST_getState(obj->estHandle);
    
      // Get the DC buss voltage
      gMotorVars.VdcBus_kV = _IQmpy(gAdcData.dcBus,_IQ(USER_IQ_FULL_SCALE_VOLTAGE_V/1000.0));
    
      return;
    } // end of updateGlobalVariables_motor() function
    
    
    void recalcKpKi(CTRL_Handle handle)
    {
      CTRL_Obj *obj = (CTRL_Obj *)handle;
      EST_State_e EstState = EST_getState(obj->estHandle);
    
      if((EST_isMotorIdentified(obj->estHandle) == false) && (EstState == EST_State_Rs))
        {
          float_t Lhf = CTRL_getLhf(handle);
          float_t Rhf = CTRL_getRhf(handle);
          float_t RhfoverLhf = Rhf/Lhf;
          _iq Kp = _IQ(0.25*Lhf*USER_IQ_FULL_SCALE_CURRENT_A/(USER_CTRL_PERIOD_sec*USER_IQ_FULL_SCALE_VOLTAGE_V));
          _iq Ki = _IQ(RhfoverLhf*USER_CTRL_PERIOD_sec);
    
          // set Rhf/Lhf
          CTRL_setRoverL(handle,RhfoverLhf);
    
          // set the controller proportional gains
          CTRL_setKp(handle,CTRL_Type_PID_Id,Kp);
          CTRL_setKp(handle,CTRL_Type_PID_Iq,Kp);
    
          // set the Id controller gains
          CTRL_setKi(handle,CTRL_Type_PID_Id,Ki);
          PID_setKi(obj->pidHandle_Id,Ki);
    
          // set the Iq controller gains
          CTRL_setKi(handle,CTRL_Type_PID_Iq,Ki);
          PID_setKi(obj->pidHandle_Iq,Ki);
        }
    
      return;
    } // end of recalcKpKi() function
    
    
    void setFeLimitZero(CTRL_Handle handle)
    {
      CTRL_Obj *obj = (CTRL_Obj *)handle;
      EST_State_e EstState = EST_getState(obj->estHandle);
    
      _iq fe_neg_max_pu;
      _iq fe_pos_min_pu;
    
      if((EST_isMotorIdentified(obj->estHandle) == false) && (CTRL_getMotorType(handle) == MOTOR_Type_Induction))
        {
          fe_neg_max_pu = _IQ30(0.0);
    
          fe_pos_min_pu = _IQ30(0.0);
        }
      else
        {
          fe_neg_max_pu = _IQ30(-USER_ZEROSPEEDLIMIT);
    
          fe_pos_min_pu = _IQ30(USER_ZEROSPEEDLIMIT);
        }
    
      EST_setFe_neg_max_pu(obj->estHandle, fe_neg_max_pu);
    
      EST_setFe_pos_min_pu(obj->estHandle, fe_pos_min_pu);
    
      return;
    } // end of setFeLimitZero() function
    
    
    void acim_Dir_qFmtCalc(CTRL_Handle handle)
    {
      CTRL_Obj *obj = (CTRL_Obj *)handle;
      EST_State_e EstState = EST_getState(obj->estHandle);
    
      if(EstState == EST_State_IdRated)
        {
          EST_setDir_qFmt(obj->estHandle, EST_computeDirection_qFmt(obj->estHandle, 0.7));
        }
    
      return;
    } // end of acim_Dir_qFmtCalc() function
    
    
    //@} //defgroup
    // end of file
    
    
    
    

    There are no errors in the code, but the motor isn't running when commands are is used. Please check the main.c file for any issues and any changes in a code. Please let me know.

  • Hi Jason Osborn

    "Thank you for the information. I have added the sci function as specified in the pie.c and hal.h files." What is next step ? Please let me know.

  • Hello,

    Have you followed the steps present in the motorware_hal_tutorial.pdf document, section 6.7? This describes every step of the process. If you have followed this process, what issues are you still facing?

    Regards,
    Jason Osborn

  • Hi Jason Osborn

    I have followed the steps as per in the motorware_hal_tutorial.pdf document, section 6.7. There are no errors, but the motor isn't running when commands are is used. Please check the main.c file for any issues and any changes in a code. The main.c file added above. Please let me know.

  • Kishor,

    I can look over the initialization process in main(void), but I cannot look over the full file- this is unlikely to help, as I don't have any more details on the issue.

    The following will help me determine the issue.

    1. Are you able to run the motor through the CCS expressions window? (i.e. NOT using SCI/UART)
      1. If so, the issue is in the SCI implementation.

    2. What is the base lab that you're working with? In your original post, you mention lab 2b, but the SCI/UART functionality example is for lab 11. While the two labs should be similar, they're not identical. Have you looked for any differences and accounted for them in your implementation?

    3. Add counters to the motor control and UART ISRs. This will allow you to verify that the code is actually executing.
      1. Add the following global variables to the main.c file:
        1. uint32_t counterMotorISR = 0;
        2. uint32_t counterUARTISR = 0;
      2. Add the following line of code to the motor control ISR:
        1. counterMotorISR++;
      3. Add the following line of code to the UART ISR:
        1. counterUARTISR++;
      4. Add both variables to the CCS expressions window. During runtime, verify that both are incrementing.

    Let me know the outcome of these questions.

    Regards,
    Jason Osborn

  • Hi  Jason Osborn

    Thank you for your support However, I'm not sure how to implement the SCI/UART functions in my project. Could you please provide code for UART commands to control a motor?

  • Hi  Jason Osborn

    Thank you for your support However, I'm not sure how to implement the SCI/UART functions in my project. Could you please provide code for UART commands to control a motor? 

  • Apologies for the delay in response.

    The UART code in the HAL tutorial, as well as the SCI/UART tutorials present in C2000Ware, are the extent of the example code provided by Texas Instruments. To assist further, I would need responses to my prior questions.

    Regards,
    Jason Osborn

  • Hi Jason Osborn

    I have a question regarding the project lab examples. I'm using a flash file in GUI Composer to operate a motor. Is it possible to run the motor without using the GUI? Please let me know.

  • Yes. MotorWare and Code Composer Studio allows you to use the project through CCS.

    Regards,
    Jason Osborn

  • Hi Jason Osborn

    // system includes
    #include <math.h>
    #include "main.h"
    
    
    #include "sw/drivers/sci/src/32b/f28x/f2802x/sci.h"
    #include "hal.h"
    #include "hal_obj.h"
    
    
    
    //Added
    // Define motor control and UART variables
    bool isMotorOn = false;
    bool isWaitingTxFifoEmpty = false;
    bool isTxOffDelayActive = false;
    int txOffDelayCounter = 0;
    int txOffDelayCount = 1000;  // Example delay count
    int counter = 0;
    char buf[8];
    char returnBuf[8];
    
    // Added
    
    uint16_t boardId = '5';
    
    volatile bool isVoltageTooLow = true;
    _iq lowVoltageThreshold = _IQ(0.01);
    
    bool isCommandReceived = false;
    bool isCommandStart = false;
    bool isOpenLoop = false;
    bool shouldSendSpeed = false;
    
    
    // Constants for command processing
    #define BUF_SIZE 8
    #define CMD_RX_ON "RX_ON"
    #define CMD_RX_OFF "RX_OFF"
    
    
    // Globals for UART and motor control
    static char buf[BUF_SIZE];
    //static int counter = 0;
    //static bool isMotorOn = false;
    
    
    #ifdef FLASH
    #pragma CODE_SECTION(mainISR,"ramfuncs");
    #endif
    
    // Include header files used in the main function
    
    // **************************************************************************
    // the defines
    
    // **************************************************************************
    // the globals
    
    CLARKE_Handle   clarkeHandle_I;  //!< the handle for the current Clarke
                                     //!< transform
    CLARKE_Obj      clarke_I;        //!< the current Clarke transform object
    
    CLARKE_Handle   clarkeHandle_V;  //!< the handle for the voltage Clarke
                                     //!< transform
    CLARKE_Obj      clarke_V;        //!< the voltage Clarke transform object
    
    EST_Handle      estHandle;       //!< the handle for the estimator
    
    PID_Obj         pid[3];          //!< three objects for PID controllers
                                     //!< 0 - Speed, 1 - Id, 2 - Iq
    PID_Handle      pidHandle[3];    //!< three handles for PID controllers
                                     //!< 0 - Speed, 1 - Id, 2 - Iq
    uint16_t        pidCntSpeed;     //!< count variable to decimate the execution
                                     //!< of the speed PID controller
    
    IPARK_Handle    iparkHandle;     //!< the handle for the inverse Park
                                     //!< transform
    IPARK_Obj       ipark;           //!< the inverse Park transform object
    
    SVGEN_Handle    svgenHandle;     //!< the handle for the space vector generator
    SVGEN_Obj       svgen;           //!< the space vector generator object
    
    #ifdef CSM_ENABLE
    #pragma DATA_SECTION(halHandle,"rom_accessed_data");
    #endif
    HAL_Handle      halHandle;       //!< the handle for the hardware abstraction
                                     //!< layer (HAL)
    
    HAL_PwmData_t   gPwmData = {_IQ(0.0),_IQ(0.0),_IQ(0.0)};  //!< contains the
                                     //!< pwm values for each phase.
                                     //!< -1.0 is 0%, 1.0 is 100%
    
    HAL_AdcData_t   gAdcData;        //!< contains three current values, three
                                     //!< voltage values and one DC buss value
    
    MATH_vec3       gOffsets_I_pu = {_IQ(0.0),_IQ(0.0),_IQ(0.0)};  //!< contains
                                     //!< the offsets for the current feedback
    
    MATH_vec3       gOffsets_V_pu = {_IQ(0.0),_IQ(0.0),_IQ(0.0)};  //!< contains
                                     //!< the offsets for the voltage feedback
    
    MATH_vec2       gIdq_ref_pu = {_IQ(0.0),_IQ(0.0)};  //!< contains the Id and
                                     //!< Iq references
    
    MATH_vec2       gVdq_out_pu = {_IQ(0.0),_IQ(0.0)};  //!< contains the output
                                     //!< Vd and Vq from the current controllers
    
    MATH_vec2       gIdq_pu = {_IQ(0.0),_IQ(0.0)};  //!< contains the Id and Iq
                                     //!< measured values
    
    #ifdef CSM_ENABLE
    #pragma DATA_SECTION(gUserParams,"rom_accessed_data");
    #endif
    USER_Params     gUserParams;
    
    volatile MOTOR_Vars_t gMotorVars = MOTOR_Vars_INIT;   //!< the global motor
                                     //!< variables that are defined in main.h and
                                     //!< used for display in the debugger's watch
                                     //!< window
    
    #ifdef FLASH
    // Used for running BackGround in flash, and ISR in RAM
    extern uint16_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
    
    #ifdef CSM_ENABLE
    extern uint16_t *econst_start, *econst_end, *econst_ram_load;
    extern uint16_t *switch_start, *switch_end, *switch_ram_load;
    #endif
    
    #endif
    
    #ifdef DRV8301_SPI
    // Watch window interface to the 8301 SPI
    DRV_SPI_8301_Vars_t gDrvSpi8301Vars;
    #endif
    
    #ifdef DRV8305_SPI
    // Watch window interface to the 8305 SPI
    DRV_SPI_8305_Vars_t gDrvSpi8305Vars;
    #endif
    
    _iq gFlux_pu_to_Wb_sf;
    
    _iq gFlux_pu_to_VpHz_sf;
    
    _iq gTorque_Ls_Id_Iq_pu_to_Nm_sf;
    
    _iq gTorque_Flux_Iq_pu_to_Nm_sf;
    
    _iq gSpeed_krpm_to_pu_sf = _IQ((float_t)USER_MOTOR_NUM_POLE_PAIRS * 1000.0
                / (USER_IQ_FULL_SCALE_FREQ_Hz * 60.0));
    
    _iq gSpeed_hz_to_krpm_sf = _IQ(60.0 / (float_t)USER_MOTOR_NUM_POLE_PAIRS
                / 1000.0);
    
    // **************************************************************************
    // the functions
    void main(void)
    {
        // IMPORTANT NOTE: If you are not familiar with MotorWare coding guidelines
        // please refer to the following document:
        // C:/ti/motorware/motorware_1_01_00_1x/docs/motorware_coding_standards.pdf
    
        // Only used if running from FLASH
        // Note that the variable FLASH is defined by the project
    
        #ifdef FLASH
        // Copy time critical code and Flash setup code to RAM
        // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
        // symbols are created by the linker. Refer to the linker files.
        memCopy((uint16_t *)&RamfuncsLoadStart,(uint16_t *)&RamfuncsLoadEnd,
                (uint16_t *)&RamfuncsRunStart);
    
        #ifdef CSM_ENABLE
          //copy .econst to unsecure RAM
          if(*econst_end - *econst_start)
            {
              memCopy((uint16_t *)&econst_start,(uint16_t *)&econst_end,(uint16_t *)&econst_ram_load);
            }
    
          //copy .switch ot unsecure RAM
          if(*switch_end - *switch_start)
            {
              memCopy((uint16_t *)&switch_start,(uint16_t *)&switch_end,(uint16_t *)&switch_ram_load);
            }
        #endif
        #endif
    
        // initialize the Hardware Abstraction Layer  (HAL)
        // halHandle will be used throughout the code to interface with the HAL
        // (set parameters, get and set functions, etc) halHandle is required since
        // this is how all objects are interfaced, and it allows interface with
        // multiple objects by simply passing a different handle. The use of
        // handles is explained in this document:
        // C:/ti/motorware/motorware_1_01_00_1x/docs/motorware_coding_standards.pdf
        halHandle = HAL_init(&hal,sizeof(hal));
    
        // check for errors in user parameters
        USER_checkForErrors(&gUserParams);
    
        // store user parameter error in global variable
        gMotorVars.UserErrorCode = USER_getErrorCode(&gUserParams);
    
        // do not allow code execution if there is a user parameter error. If there
        // is an error, the code will be stuck in this forever loop
        if(gMotorVars.UserErrorCode != USER_ErrorCode_NoError)
        {
            for(;;)
            {
                gMotorVars.Flag_enableSys = false;
            }
        }
    
        // initialize the Clarke modules
        // Clarke handle initialization for current signals
        clarkeHandle_I = CLARKE_init(&clarke_I,sizeof(clarke_I));
        // Clarke handle initialization for voltage signals
        clarkeHandle_V = CLARKE_init(&clarke_V,sizeof(clarke_V));
    
        // initialize the estimator
        estHandle = EST_init((void *)USER_EST_HANDLE_ADDRESS,0x200);
    
        // initialize the user parameters
        // This function initializes all values of structure gUserParams with
        // values defined in user.h. The values in gUserParams will be then used by
        // the hardware abstraction layer (HAL) to configure peripherals such as
        // PWM, ADC, interrupts, etc.
        USER_setParams(&gUserParams);
    
        // set the hardware abstraction layer parameters
        // This function initializes all peripherals through a Hardware Abstraction
        // Layer (HAL). It uses all values stored in gUserParams.
        HAL_setParams(halHandle,&gUserParams);
    
        #ifdef FAST_ROM_V1p6
        {
            // These function calls are used to initialize the estimator with ROM
            // function calls. It needs the specific address where the controller
            // object is declared by the ROM code.
            CTRL_Handle ctrlHandle = CTRL_init((void *)USER_CTRL_HANDLE_ADDRESS
                                ,0x200);
            CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle;
    
            // this sets the estimator handle (part of the controller object) to
            // the same value initialized above by the EST_init() function call.
            // This is done so the next function implemented in ROM, can
            // successfully initialize the estimator as part of the controller
            // object.
            obj->estHandle = estHandle;
    
            // initialize the estimator through the controller. These three
            // function calls are needed for the F2806xF/M implementation of
            // InstaSPIN.
            CTRL_setParams(ctrlHandle,&gUserParams);
            CTRL_setUserMotorParams(ctrlHandle);
            CTRL_setupEstIdleState(ctrlHandle);
        }
        #else
        {
            // initialize the estimator. These two function calls are needed for
            // the F2802xF implementation of InstaSPIN using the estimator handle
            // initialized by EST_init(), these two function calls configure the
            // estimator, and they set the estimator in a proper state prior to
            // spinning a motor.
            EST_setEstParams(estHandle,&gUserParams);
            EST_setupEstIdleState(estHandle);
        }
        #endif
    
        // disable Rs recalculation
        // **NOTE: changing the input parameter from 'false' to 'true' will cause
        // **      run time issues. Lab11 does not support Rs Online function
        //
        EST_setFlag_enableRsRecalc(estHandle,false);
    
        // set the number of current sensors
        setupClarke_I(clarkeHandle_I,USER_NUM_CURRENT_SENSORS);
    
        // set the number of voltage sensors
        setupClarke_V(clarkeHandle_V,USER_NUM_VOLTAGE_SENSORS);
    
        // set the pre-determined current and voltage feeback offset values
        gOffsets_I_pu.value[0] = _IQ(I_A_offset);
        gOffsets_I_pu.value[1] = _IQ(I_B_offset);
        gOffsets_I_pu.value[2] = _IQ(I_C_offset);
        gOffsets_V_pu.value[0] = _IQ(V_A_offset);
        gOffsets_V_pu.value[1] = _IQ(V_B_offset);
        gOffsets_V_pu.value[2] = _IQ(V_C_offset);
    
        // initialize the PID controllers
        {
            // This equation defines the relationship between per unit current and
            // real-world current. The resulting value in per units (pu) is then
            // used to configure the controllers
            _iq maxCurrent_pu = _IQ(USER_MOTOR_MAX_CURRENT
                        / USER_IQ_FULL_SCALE_CURRENT_A);
    
            // This equation uses the scaled maximum voltage vector, which is
            // already in per units, hence there is no need to include the #define
            // for USER_IQ_FULL_SCALE_VOLTAGE_V
            _iq maxVoltage_pu = _IQ(USER_MAX_VS_MAG_PU * USER_VD_SF);
    
            float_t fullScaleCurrent = USER_IQ_FULL_SCALE_CURRENT_A;
            float_t fullScaleVoltage = USER_IQ_FULL_SCALE_VOLTAGE_V;
            float_t IsrPeriod_sec = 1.0 / USER_ISR_FREQ_Hz;
            float_t Ls_d = USER_MOTOR_Ls_d;
            float_t Ls_q = USER_MOTOR_Ls_q;
            float_t Rs = USER_MOTOR_Rs;
    
            // This lab assumes that motor parameters are known, and it does not
            // perform motor ID, so the R/L parameters are known and defined in
            // user.h
            float_t RoverLs_d = Rs / Ls_d;
            float_t RoverLs_q = Rs / Ls_q;
    
            // For the current controller, Kp = Ls*bandwidth(rad/sec)  But in order
            // to be used, it must be converted to per unit values by multiplying
            // by fullScaleCurrent and then dividing by fullScaleVoltage.  From the
            // statement below, we see that the bandwidth in rad/sec is equal to
            // 0.25/IsrPeriod_sec, which is equal to USER_ISR_FREQ_HZ/4. This means
            // that by setting Kp as described below, the bandwidth in Hz is
            // USER_ISR_FREQ_HZ/(8*pi).
            _iq Kp_Id = _IQ((0.25 * Ls_d * fullScaleCurrent) / (IsrPeriod_sec
                        * fullScaleVoltage));
    
            // In order to achieve pole/zero cancellation (which reduces the
            // closed-loop transfer function from a second-order system to a
            // first-order system), Ki must equal Rs/Ls.  Since the output of the
            // Ki gain stage is integrated by a DIGITAL integrator, the integrator
            // input must be scaled by 1/IsrPeriod_sec.  That's just the way
            // digital integrators work.  But, since IsrPeriod_sec is a constant,
            // we can save an additional multiplication operation by lumping this
            // term with the Ki value.
            _iq Ki_Id = _IQ(RoverLs_d * IsrPeriod_sec);
    
            // Now do the same thing for Kp for the q-axis current controller.
            // If the motor is not an IPM motor, Ld and Lq are the same, which
            // means that Kp_Iq = Kp_Id
            _iq Kp_Iq = _IQ((0.25 * Ls_q * fullScaleCurrent) / (IsrPeriod_sec
                        * fullScaleVoltage));
    
            // Do the same thing for Ki for the q-axis current controller.  If the
            // motor is not an IPM motor, Ld and Lq are the same, which means that
            // Ki_Iq = Ki_Id.
            _iq Ki_Iq = _IQ(RoverLs_q * IsrPeriod_sec);
    
            // There are three PI controllers; one speed controller and two current
            // controllers.  Each PI controller has two coefficients; Kp and Ki.
            // So you have a total of six coefficients that must be defined.
            // This is for the speed controller
            pidHandle[0] = PID_init(&pid[0],sizeof(pid[0]));
            // This is for the Id current controller
            pidHandle[1] = PID_init(&pid[1],sizeof(pid[1]));
            // This is for the Iq current controller
            pidHandle[2] = PID_init(&pid[2],sizeof(pid[2]));
    
            // The following instructions load the parameters for the speed PI
            // controller.
            PID_setGains(pidHandle[0],_IQ(1.0),_IQ(0.01),_IQ(0.0));
    
            // The current limit is performed by the limits placed on the speed PI
            // controller output.  In the following statement, the speed
            // controller's largest negative current is set to -maxCurrent_pu, and
            // the largest positive current is set to maxCurrent_pu.
            PID_setMinMax(pidHandle[0],-maxCurrent_pu,maxCurrent_pu);
            PID_setUi(pidHandle[0],_IQ(0.0));  // Set the initial condition value
                                               // for the integrator output to 0
    
            pidCntSpeed = 0;  // Set the counter for decimating the speed
                              // controller to 0
    
            // The following instructions load the parameters for the d-axis
            // current controller.
            // P term = Kp_Id, I term = Ki_Id, D term = 0
            PID_setGains(pidHandle[1],Kp_Id,Ki_Id,_IQ(0.0));
    
            // Largest negative voltage = -maxVoltage_pu, largest positive
            // voltage = maxVoltage_pu
            PID_setMinMax(pidHandle[1],-maxVoltage_pu,maxVoltage_pu);
    
            // Set the initial condition value for the integrator output to 0
            PID_setUi(pidHandle[1],_IQ(0.0));
    
            // The following instructions load the parameters for the q-axis
            // current controller.
            // P term = Kp_Iq, I term = Ki_Iq, D term = 0
            PID_setGains(pidHandle[2],Kp_Iq,Ki_Iq,_IQ(0.0));
    
            // The largest negative voltage = 0 and the largest positive
            // voltage = 0.  But these limits are updated every single ISR before
            // actually executing the Iq controller. The limits depend on how much
            // voltage is left over after the Id controller executes. So having an
            // initial value of 0 does not affect Iq current controller execution.
            PID_setMinMax(pidHandle[2],_IQ(0.0),_IQ(0.0));
    
            // Set the initial condition value for the integrator output to 0
            PID_setUi(pidHandle[2],_IQ(0.0));
        }
    
        // initialize the speed reference in kilo RPM where base speed is
        // USER_IQ_FULL_SCALE_FREQ_Hz.
        // Set 10 Hz electrical frequency as initial value, so the kRPM value would
        // be: 10 * 60 / motor pole pairs / 1000.
        gMotorVars.SpeedRef_krpm = _IQmpy(_IQ(10.0),gSpeed_hz_to_krpm_sf);
    
        // initialize the inverse Park module
        iparkHandle = IPARK_init(&ipark,sizeof(ipark));
    
        // initialize the space vector generator module
        svgenHandle = SVGEN_init(&svgen,sizeof(svgen));
    
        // setup faults
        HAL_setupFaults(halHandle);
    
        // initialize the interrupt vector table
        HAL_initIntVectorTable(halHandle);
    
        // enable the ADC interrupts
        HAL_enableAdcInts(halHandle);
    
        // enable global interrupts
        HAL_enableGlobalInts(halHandle);
    
        // enable debug interrupts
        HAL_enableDebugInt(halHandle);
    
        // disable the PWM
        HAL_disablePwm(halHandle);
    
        // compute scaling factors for flux and torque calculations
        gFlux_pu_to_Wb_sf = USER_computeFlux_pu_to_Wb_sf();
        gFlux_pu_to_VpHz_sf = USER_computeFlux_pu_to_VpHz_sf();
        gTorque_Ls_Id_Iq_pu_to_Nm_sf = USER_computeTorque_Ls_Id_Iq_pu_to_Nm_sf();
        gTorque_Flux_Iq_pu_to_Nm_sf = USER_computeTorque_Flux_Iq_pu_to_Nm_sf();
    
        // enable the system by default
        gMotorVars.Flag_enableSys = true;
    
        #ifdef DRV8301_SPI
            // turn on the DRV8301 if present
            HAL_enableDrv(halHandle);
            // initialize the DRV8301 interface
            HAL_setupDrvSpi(halHandle,&gDrvSpi8301Vars);
        #endif
    
        #ifdef DRV8305_SPI
            // turn on the DRV8305 if present
            HAL_enableDrv(halHandle);
            // initialize the DRV8305 interface
            HAL_setupDrvSpi(halHandle,&gDrvSpi8305Vars);
        #endif
    
        // Begin the background loop
        for(;;)
        {
            // Waiting for enable system flag to be set
            while(!(gMotorVars.Flag_enableSys));
    
            // loop while the enable system flag is true
            while(gMotorVars.Flag_enableSys)
            {
                // If Flag_enableSys is set AND Flag_Run_Identify is set THEN
                // enable PWMs and set the speed reference
                if(gMotorVars.Flag_Run_Identify)
                {
                    // update estimator state
                    EST_updateState(estHandle,0);
    
                    #ifdef FAST_ROM_V1p6
                        // call this function to fix 1p6. This is only used for
                        // F2806xF/M implementation of InstaSPIN (version 1.6 of
                        // ROM), since the inductance calculation is not done
                        // correctly in ROM, so this function fixes that ROM bug.
                        softwareUpdate1p6(estHandle);
                    #endif
    
                    // enable the PWM
                    HAL_enablePwm(halHandle);
                }
                else  // Flag_enableSys is set AND Flag_Run_Identify is not set
                {
                    // set estimator to Idle
                    EST_setIdle(estHandle);
    
                    // disable the PWM
                    HAL_disablePwm(halHandle);
    
                    // clear integrator outputs
                    PID_setUi(pidHandle[0],_IQ(0.0));
                    PID_setUi(pidHandle[1],_IQ(0.0));
                    PID_setUi(pidHandle[2],_IQ(0.0));
    
                    // clear Id and Iq references
                    gIdq_ref_pu.value[0] = _IQ(0.0);
                    gIdq_ref_pu.value[1] = _IQ(0.0);
                }
    
                // update the global variables
                updateGlobalVariables(estHandle);
    
                // enable/disable the forced angle
                EST_setFlag_enableForceAngle(estHandle,
                        gMotorVars.Flag_enableForceAngle);
    
                // set target speed
                gMotorVars.SpeedRef_pu = _IQmpy(gMotorVars.SpeedRef_krpm,
                        gSpeed_krpm_to_pu_sf);
    
                #ifdef DRV8301_SPI
                    HAL_writeDrvData(halHandle,&gDrvSpi8301Vars);
    
                    HAL_readDrvData(halHandle,&gDrvSpi8301Vars);
                #endif
                #ifdef DRV8305_SPI
                    HAL_writeDrvData(halHandle,&gDrvSpi8305Vars);
    
                    HAL_readDrvData(halHandle,&gDrvSpi8305Vars);
                #endif
    
            } // end of while(gFlag_enableSys) loop
    
            // disable the PWM
            HAL_disablePwm(halHandle);
    
            gMotorVars.Flag_Run_Identify = false;
        } // end of for(;;) loop
    } // end of main() function
    
    
    //! \brief     The main ISR that implements the motor control.
    interrupt void mainISR(void)
    {
        // Declaration of local variables
        _iq angle_pu = _IQ(0.0);
        _iq speed_pu = _IQ(0.0);
        _iq oneOverDcBus;
        MATH_vec2 Iab_pu;
        MATH_vec2 Vab_pu;
        MATH_vec2 phasor;
    
        // acknowledge the ADC interrupt
        HAL_acqAdcInt(halHandle,ADC_IntNumber_1);
    
        // convert the ADC data
        HAL_readAdcDataWithOffsets(halHandle,&gAdcData);
    
        // remove offsets
        gAdcData.I.value[0] = gAdcData.I.value[0] - gOffsets_I_pu.value[0];
        gAdcData.I.value[1] = gAdcData.I.value[1] - gOffsets_I_pu.value[1];
        gAdcData.I.value[2] = gAdcData.I.value[2] - gOffsets_I_pu.value[2];
        gAdcData.V.value[0] = gAdcData.V.value[0] - gOffsets_V_pu.value[0];
        gAdcData.V.value[1] = gAdcData.V.value[1] - gOffsets_V_pu.value[1];
        gAdcData.V.value[2] = gAdcData.V.value[2] - gOffsets_V_pu.value[2];
    
        // run Clarke transform on current.  Three values are passed, two values
        // are returned.
        CLARKE_run(clarkeHandle_I,&gAdcData.I,&Iab_pu);
    
        // run Clarke transform on voltage.  Three values are passed, two values
        // are returned.
        CLARKE_run(clarkeHandle_V,&gAdcData.V,&Vab_pu);
    
        // run the estimator
        // The speed reference is needed so that the proper sign of the forced
        // angle is calculated. When the estimator does not do motor ID as in this
        // lab, only the sign of the speed reference is used
        EST_run(estHandle,&Iab_pu,&Vab_pu,gAdcData.dcBus,gMotorVars.SpeedRef_pu);
    
        // generate the motor electrical angle
        angle_pu = EST_getAngle_pu(estHandle);
        speed_pu = EST_getFm_pu(estHandle);
    
        // get Idq from estimator to avoid sin and cos, and a Park transform,
        // which saves CPU cycles
        EST_getIdq_pu(estHandle,&gIdq_pu);
    
        // run the appropriate controller
        if(gMotorVars.Flag_Run_Identify)
        {
            // Declaration of local variables.
            _iq refValue;
            _iq fbackValue;
            _iq outMax_pu;
    
            // when appropriate, run the PID speed controller
            // This mechanism provides the decimation for the speed loop.
            if(pidCntSpeed >= USER_NUM_CTRL_TICKS_PER_SPEED_TICK)
            {
                // Reset the Speed PID execution counter.
                pidCntSpeed = 0;
    
                // The next instruction executes the PI speed controller and places
                // its output in Idq_ref_pu.value[1], which is the input reference
                // value for the q-axis current controller.
                PID_run_spd(pidHandle[0],gMotorVars.SpeedRef_pu,speed_pu,
                        &(gIdq_ref_pu.value[1]));
            }
            else
            {
                // increment counter
                pidCntSpeed++;
            }
    
            // Get the reference value for the d-axis current controller.
            refValue = gIdq_ref_pu.value[0];
    
            // Get the actual value of Id
            fbackValue = gIdq_pu.value[0];
    
            // The next instruction executes the PI current controller for the
            // d axis and places its output in Vdq_pu.value[0], which is the
            // control voltage along the d-axis (Vd)
            PID_run(pidHandle[1],refValue,fbackValue,&(gVdq_out_pu.value[0]));
    
            // get the Iq reference value
            refValue = gIdq_ref_pu.value[1];
    
            // get the actual value of Iq
            fbackValue = gIdq_pu.value[1];
    
            // The voltage limits on the output of the q-axis current controller
            // are dynamic, and are dependent on the output voltage from the d-axis
            // current controller.  In other words, the d-axis current controller
            // gets first dibs on the available voltage, and the q-axis current
            // controller gets what's left over.  That is why the d-axis current
            // controller executes first. The next instruction calculates the
            // maximum limits for this voltage as:
            // Vq_min_max = +/- sqrt(Vbus^2 - Vd^2)
            outMax_pu = _IQsqrt(_IQ(USER_MAX_VS_MAG_PU * USER_MAX_VS_MAG_PU)
                    - _IQmpy(gVdq_out_pu.value[0],gVdq_out_pu.value[0]));
    
            // Set the limits to +/- outMax_pu
            PID_setMinMax(pidHandle[2],-outMax_pu,outMax_pu);
    
            // The next instruction executes the PI current controller for the
            // q axis and places its output in Vdq_pu.value[1], which is the
            // control voltage vector along the q-axis (Vq)
            PID_run(pidHandle[2],refValue,fbackValue,&(gVdq_out_pu.value[1]));
    
            // The voltage vector is now calculated and ready to be applied to the
            // motor in the form of three PWM signals.  However, even though the
            // voltages may be supplied to the PWM module now, they won't be
            // applied to the motor until the next PWM cycle. By this point, the
            // motor will have moved away from the angle that the voltage vector
            // was calculated for, by an amount which is proportional to the
            // sampling frequency and the speed of the motor.  For steady-state
            // speeds, we can calculate this angle delay and compensate for it.
            angle_pu = angleDelayComp(speed_pu,angle_pu);
    
            // compute the sine and cosine phasor values which are part of the inverse
            // Park transform calculations. Once these values are computed,
            // they are copied into the IPARK module, which then uses them to
            // transform the voltages from DQ to Alpha/Beta reference frames.
            phasor.value[0] = _IQcosPU(angle_pu);
            phasor.value[1] = _IQsinPU(angle_pu);
    
            // set the phasor in the inverse Park transform
            IPARK_setPhasor(iparkHandle,&phasor);
    
            // Run the inverse Park module.  This converts the voltage vector from
            // synchronous frame values to stationary frame values.
            IPARK_run(iparkHandle,&gVdq_out_pu,&Vab_pu);
    
            // These 3 statements compensate for variations in the DC bus by adjusting the
            // PWM duty cycle. The goal is to achieve the same volt-second product
            // regardless of the DC bus value.  To do this, we must divide the desired voltage
            // values by the DC bus value.  Or...it is easier to multiply by 1/(DC bus value).
            oneOverDcBus = EST_getOneOverDcBus_pu(estHandle);
            Vab_pu.value[0] = _IQmpy(Vab_pu.value[0],oneOverDcBus);
            Vab_pu.value[1] = _IQmpy(Vab_pu.value[1],oneOverDcBus);
    
            // Now run the space vector generator (SVGEN) module.
            // There is no need to do an inverse CLARKE transform, as this is
            // handled in the SVGEN_run function.
            SVGEN_run(svgenHandle,&Vab_pu,&(gPwmData.Tabc));
        }
        else  // gMotorVars.Flag_Run_Identify = 0
        {
            // disable the PWM
            HAL_disablePwm(halHandle);
    
            // Set the PWMs to 50% duty cycle
            gPwmData.Tabc.value[0] = _IQ(0.0);
            gPwmData.Tabc.value[1] = _IQ(0.0);
            gPwmData.Tabc.value[2] = _IQ(0.0);
        }
    
        // write to the PWM compare registers, and then we are done!
        HAL_writePwmData(halHandle,&gPwmData);
    
        return;
    } // end of mainISR() function
    
    
    //! \brief  The angleDelayComp function compensates for the delay introduced
    //! \brief  from the time when the system inputs are sampled to when the PWM
    //! \brief  voltages are applied to the motor windings.
    _iq angleDelayComp(const _iq fm_pu,const _iq angleUncomp_pu)
    {
        _iq angleDelta_pu = _IQmpy(fm_pu,_IQ(USER_IQ_FULL_SCALE_FREQ_Hz
                    / (USER_PWM_FREQ_kHz*1000.0)));
        _iq angleCompFactor = _IQ(1.0 + (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK
                    * 0.5);
        _iq angleDeltaComp_pu = _IQmpy(angleDelta_pu,angleCompFactor);
        uint32_t angleMask = ((uint32_t)0xFFFFFFFF >> (32 - GLOBAL_Q));
        _iq angleComp_pu;
        _iq angleTmp_pu;
    
        // increment the angle
        angleTmp_pu = angleUncomp_pu + angleDeltaComp_pu;
    
        // mask the angle for wrap around
        // note: must account for the sign of the angle
        angleComp_pu = _IQabs(angleTmp_pu) & angleMask;
    
        // account for sign
        if(angleTmp_pu < _IQ(0.0))
        {
            angleComp_pu = -angleComp_pu;
        }
    
        return(angleComp_pu);
    } // end of angleDelayComp() function
    
    
    //! \brief  Call this function to fix 1p6. This is only used for F2806xF/M
    //! \brief  implementation of InstaSPIN (version 1.6 of ROM) since the
    //! \brief  inductance calculation is not done correctly in ROM, so this
    //! \brief  function fixes that ROM bug.
    void softwareUpdate1p6(EST_Handle handle)
    {
        float_t fullScaleInductance = USER_IQ_FULL_SCALE_VOLTAGE_V
                        / (USER_IQ_FULL_SCALE_CURRENT_A
                        * USER_VOLTAGE_FILTER_POLE_rps);
        float_t Ls_coarse_max = _IQ30toF(EST_getLs_coarse_max_pu(handle));
        int_least8_t lShift = ceil(log(USER_MOTOR_Ls_d / (Ls_coarse_max
                             * fullScaleInductance)) / log(2.0));
        uint_least8_t Ls_qFmt = 30 - lShift;
        float_t L_max = fullScaleInductance * pow(2.0,lShift);
        _iq Ls_d_pu = _IQ30(USER_MOTOR_Ls_d / L_max);
        _iq Ls_q_pu = _IQ30(USER_MOTOR_Ls_q / L_max);
    
        // store the results
        EST_setLs_d_pu(handle,Ls_d_pu);
        EST_setLs_q_pu(handle,Ls_q_pu);
        EST_setLs_qFmt(handle,Ls_qFmt);
    
        return;
    } // end of softwareUpdate1p6() function
    
    
    //! \brief     Setup the Clarke transform for either 2 or 3 sensors.
    //! \param[in] handle             The clarke (CLARKE) handle
    //! \param[in] numCurrentSensors  The number of current sensors
    void setupClarke_I(CLARKE_Handle handle,const uint_least8_t numCurrentSensors)
    {
        _iq alpha_sf,beta_sf;
    
        // initialize the Clarke transform module for current
        if(numCurrentSensors == 3)
        {
            alpha_sf = _IQ(MATH_ONE_OVER_THREE);
            beta_sf = _IQ(MATH_ONE_OVER_SQRT_THREE);
        }
        else if(numCurrentSensors == 2)
        {
            alpha_sf = _IQ(1.0);
            beta_sf = _IQ(MATH_ONE_OVER_SQRT_THREE);
        }
        else
        {
            alpha_sf = _IQ(0.0);
            beta_sf = _IQ(0.0);
        }
    
        // set the parameters
        CLARKE_setScaleFactors(handle,alpha_sf,beta_sf);
        CLARKE_setNumSensors(handle,numCurrentSensors);
    
        return;
    } // end of setupClarke_I() function
    
    
    //! \brief     Setup the Clarke transform for either 2 or 3 sensors.
    //! \param[in] handle             The clarke (CLARKE) handle
    //! \param[in] numVoltageSensors  The number of voltage sensors
    void setupClarke_V(CLARKE_Handle handle,const uint_least8_t numVoltageSensors)
    {
        _iq alpha_sf,beta_sf;
    
        // initialize the Clarke transform module for voltage
        if(numVoltageSensors == 3)
        {
            alpha_sf = _IQ(MATH_ONE_OVER_THREE);
            beta_sf = _IQ(MATH_ONE_OVER_SQRT_THREE);
        }
        else
        {
            alpha_sf = _IQ(0.0);
            beta_sf = _IQ(0.0);
        }
    
        // In other words, the only acceptable number of voltage sensors is three.
        // set the parameters
        CLARKE_setScaleFactors(handle,alpha_sf,beta_sf);
        CLARKE_setNumSensors(handle,numVoltageSensors);
    
        return;
    } // end of setupClarke_V() function
    
    
    
    
    
    
    
    
    // UART Rx ISR
    interrupt void sciARxISR(void)
    {
        HAL_Obj *obj = (HAL_Obj *)halHandle;
    
        while (SCI_rxDataReady(obj->sciAHandle))
        {
            char c = SCI_read(obj->sciAHandle);
    
            if (counter < BUF_SIZE - 1) // -1 to leave space for null terminator
            {
                buf[counter++] = c;
    
                if (c == '>') // End of command
                {
                    buf[counter] = '\0'; // Null-terminate the command string
                    processCommand(buf);
                    counter = 0; // Reset buffer index
                }
            }
            else
            {
                // Buffer overflow, reset counter
                counter = 0;
            }
        }
    
        // Clear SCI interrupt flag
        PIE_clearInt(obj->pieHandle, PIE_GroupNumber_9);
    }
    
    // Process received command
    void processCommand(char *command)
    {
        if (strcmp(command, CMD_RX_ON) == 0)
        {
            isMotorOn = true;
            sendResponse("Motor ON");
        }
        else if (strcmp(command, CMD_RX_OFF) == 0)
        {
            isMotorOn = false;
            sendResponse("Motor OFF");
        }
        else
        {
            sendResponse("Unknown Command");
        }
    }
    
    // Send response to UART
    void sendResponse(const char *message)
    {
        int length = strlen(message);
        returnBuf[0] = '<';
        strncpy(&returnBuf[1], message, length);
        returnBuf[length + 1] = '>';
        serialWrite(returnBuf, length + 2);
    }
    
    // Write data to UART
    void serialWrite(const char *sendData, int length)
    {
        int i = 0;
        while (i < length)
        {
            if (SCI_txReady(halHandle->sciAHandle))
            {
                SCI_write(halHandle->sciAHandle, sendData[i]);
                i++;
            }
        }
        isWaitingTxFifoEmpty = true;
    }
    
    
    
    
    
    
    
    //! \brief     Update the global variables (gMotorVars).
    //! \param[in] handle  The estimator (EST) handle
    void updateGlobalVariables(EST_Handle handle)
    {
        // get the speed estimate
        gMotorVars.Speed_krpm = EST_getSpeed_krpm(handle);
    
        // get the torque estimate
        {
            _iq Flux_pu = EST_getFlux_pu(handle);
            _iq Id_pu = PID_getFbackValue(pidHandle[1]);
            _iq Iq_pu = PID_getFbackValue(pidHandle[2]);
            _iq Ld_minus_Lq_pu = _IQ30toIQ(EST_getLs_d_pu(handle)
                        - EST_getLs_q_pu(handle));
    
            // Reactance Torque
            _iq Torque_Flux_Iq_Nm = _IQmpy(_IQmpy(Flux_pu,Iq_pu),
                        gTorque_Flux_Iq_pu_to_Nm_sf);
    
            // Reluctance Torque
            _iq Torque_Ls_Id_Iq_Nm = _IQmpy(_IQmpy(_IQmpy(Ld_minus_Lq_pu,Id_pu),
                        Iq_pu),gTorque_Ls_Id_Iq_pu_to_Nm_sf);
    
            // Total torque is sum of reactance torque and reluctance torque
            _iq Torque_Nm = Torque_Flux_Iq_Nm + Torque_Ls_Id_Iq_Nm;
    
            gMotorVars.Torque_Nm = Torque_Nm;
        }
    
        // get the magnetizing current
        gMotorVars.MagnCurr_A = EST_getIdRated(handle);
    
        // get the rotor resistance
        gMotorVars.Rr_Ohm = EST_getRr_Ohm(handle);
    
        // get the stator resistance
        gMotorVars.Rs_Ohm = EST_getRs_Ohm(handle);
    
        // get the stator inductance in the direct coordinate direction
        gMotorVars.Lsd_H = EST_getLs_d_H(handle);
    
        // get the stator inductance in the quadrature coordinate direction
        gMotorVars.Lsq_H = EST_getLs_q_H(handle);
    
        // get the flux in V/Hz in floating point
        gMotorVars.Flux_VpHz = EST_getFlux_VpHz(handle);
    
        // get the flux in Wb in fixed point
        gMotorVars.Flux_Wb = _IQmpy(EST_getFlux_pu(handle),gFlux_pu_to_Wb_sf);
    
        // get the estimator state
        gMotorVars.EstState = EST_getState(handle);
    
        // Get the DC buss voltage
        gMotorVars.VdcBus_kV = _IQmpy(gAdcData.dcBus,
                _IQ(USER_IQ_FULL_SCALE_VOLTAGE_V / 1000.0));
    
        // read Vd and Vq vectors per units
        gMotorVars.Vd = gVdq_out_pu.value[0];
        gMotorVars.Vq = gVdq_out_pu.value[1];
    
        // calculate vector Vs in per units: (Vs = sqrt(Vd^2 + Vq^2))
        gMotorVars.Vs = _IQsqrt(_IQmpy(gMotorVars.Vd,gMotorVars.Vd)
                + _IQmpy(gMotorVars.Vq,gMotorVars.Vq));
    
        // read Id and Iq vectors in amps
        gMotorVars.Id_A = _IQmpy(gIdq_pu.value[0],
                _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
        gMotorVars.Iq_A = _IQmpy(gIdq_pu.value[1],
                _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
    
        // calculate vector Is in amps:  (Is_A = sqrt(Id_A^2 + Iq_A^2))
        gMotorVars.Is_A = _IQsqrt(_IQmpy(gMotorVars.Id_A,gMotorVars.Id_A)
                + _IQmpy(gMotorVars.Iq_A,gMotorVars.Iq_A));
    
        return;
    } // end of updateGlobalVariables() function
    
    //@} //defgroup
    // end of file
    
    
    

    1. In hal.h, I am added

    //Added

    extern interrupt void sciARxISR(void);

    static inline void HAL_initIntVectorTable(HAL_Handle handle)
    {

    ....

    //Added

    pie->SCIRXINTA = &sciARxISR;

    }

    //Added

    extern void HAL_setupSciA(HAL_Handle handle).
    //! \param[in] handle - the hardware abstraction (HAL) handle
    extern void HAL_enableSciInts(HAL_Handle handle);

    2. In hal.c , i am added


    HAL_Handle HAL_init(void *pMemory,const size_t numBytes)
    {

    ....

    // Added

     obj->sciAHandle = SCI_init((void *)SCIA_BASE_ADDR,sizeof(SCI_Obj));

    }

    void HAL_setParams(HAL_Handle handle,const USER_Params *pUserParams)
    {

    //Added

    // setup the sciA
    HAL_setupSciA(handle);

    }

    void HAL_setupGpios(HAL_Handle handle)
    {
    //Added

    // RX
    GPIO_setPullUp(obj->gpioHandle, GPIO_Number_28, GPIO_PullUp_Enable);
    GPIO_setQualification(obj->gpioHandle, GPIO_Number_28, GPIO_Qual_ASync);
    GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_SCIRXDA);

    // TX
    GPIO_setPullUp(obj->gpioHandle, GPIO_Number_29, GPIO_PullUp_Enable);
    GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_SCITXDA);

    }


    //Addedd

    void HAL_setupSciA(HAL_Handle handle)
    {
    HAL_Obj *obj = (HAL_Obj *)handle;
    SCI_reset(obj->sciAHandle);
    SCI_enableTx(obj->sciAHandle);
    SCI_enableRx(obj->sciAHandle);
    SCI_disableParity(obj->sciAHandle);
    SCI_setNumStopBits(obj->sciAHandle,SCI_NumStopBits_One);
    SCI_setCharLength(obj->sciAHandle,SCI_CharLength_8_Bits);
    // set baud rate to 150000
    SCI_setBaudRate(obj->sciAHandle,(SCI_BaudRate_e)(49));
    SCI_setPriority(obj->sciAHandle,SCI_Priority_FreeRun);
    SCI_enable(obj->sciAHandle);
    return;
    // end of HAL_setupSciA() function
    }

    void HAL_enableSciInts(HAL_Handle handle)
    {
    HAL_Obj *obj = (HAL_Obj *) handle;

    // enable the PIE interrupts associated with the SCI interrupts
    // enable SCIA RX interrupt in PIE
    PIE_enableInt(obj->pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIARX);

    // enable SCI RX interrupts
    // enable SCIA RX interrupt
    SCI_enableRxInt(obj->sciAHandle);

    // enable the cpu interrupt for SCI interrupts
    CPU_enableInt(obj->cpuHandle, CPU_IntNumber_9);
    } // end of HAL_enableSciInts() function

    3. In hal.obj.h, I am added 

    typedef struct _HAL_Obj_
    {

    //Added

    SCI_Handle sciAHandle;

    }

    4. In main.c, I am added

    /Added

    // enable the SCI interrupts
    HAL_enableSciInts(halHandle);

    I am working on Project 11, which utilizes SCI/UART functionality. However, I'm unable to run the motor using the commands provided. Could you please help me with this?.

  • Hello,

    If you're going to add files to your post, please try and add those files as attachments to prevent another situation where the thread causes issues with e2e.

    In order to help you further with these issues, please address the following questions. Pay particular note to the bolded text of each question:

    1. None of the following MotorWare InstaSPIN labs labelled Lab 11 explicitly require SCI/UART implementation by the user. What do you mean by project 11?
      1. If you are referring to the MotorWare HAL tutorial which uses lab 11, please note that section 6.7. 'Adding SCI/UART functionality to a Motorware project' explicitly states that lab 11 is only used as an example, and these instructions are intended to work with any InstaSPIN MotorWare project.
    2. What is the specific issue you are facing? Which of the following is the problem:
      1. Is the system failing to respond to ANY UART commands?
      2. Are specific UART commands failing? If so, which ones?
      3. Is the system immediately going into a fault state, or remaining idle?

    3. Please respond to my questions from September 17th to allow me to assist you better (direct link).

    4. What, specifically, are you referring to when you say "commands provided" ?

    Regards,
    Jason Osborn

  • Hi  Jason Osborn

    I am using Lab 11 (simplified project without CTRL object).
    I am facing issue is system falling to respond to any UART commands. 
    5344.hal.h and /cfs-file/__key/communityserver-discussions-components-files/171/7142.pie.c. The files you've sent using SCI/UART were added following the MotorWare HAL tutorial. However, the motor isn't responding to the UART commands. Is there any code available for sending UART commands to control the motor?
  • Hello,

    For code available, the UART code in the HAL tutorial, as well as the SCI/UART tutorials present in C2000Ware, are the extent of the example code provided by Texas Instruments intended to instruct on UART implementation. Various other labs, such as the MCSDK's TIDA-010265, have GUI hooks and command implementations, but these are significantly more in-depth than you need.

    • Have you confirmed that the SCI peripheral is correctly configured, particularly the baud rate, for the communication on the other end?

    • Looking at your processCommand function, I have a couple of questions.
      • What response, if any, are you receiving from the C2000?
      • If you are getting the 'unknownCommand' response, consider also setting it up such that the C2000 sends back the received message as a response as well.

    • What do your commands actually do, and how are you certain that the system is not receiving them?

    Regards,
    Jason Osborn