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.

LAUNCHXL-F28027F: SCI Initialization Problem

Part Number: LAUNCHXL-F28027F
Other Parts Discussed in Thread: BOOSTXL-DRV8305EVM, MOTORWARE, DRV8305, LAUNCHXL-F28069M

I tried to use LAUNCHXL-F28027F and BOOSTXL-DRV8305EVM.

I want to control the motor driver from Linux-PC using SCI(UART).

Then I found an example "

instaspin_foc-SCI-eCAP

"
written by maya in old thread "e2e.ti.com/.../1887277", 

The example worked, but there are some problems in startup. 

I turned on #define SCI_FIFO in sci.h.

Follow codes in void HAL_setupSCI(HAL_Handle handle) of hal.c

>>

msg = "\r\n\n ********** SCI setup is done! **********\0";
SCI_writeMsg(obj->sciaHandle, msg);

<<

makes strange forever messages like 192 192 192 ... 

.

But

after pushing HW reset SW(S2), the code works well.

And I tried to ignore these codes like this,

// msg = "\r\n\n ********** SCI setup is done! **********\0";
// SCI_writeMsg(o

The SCI returend short messages like follows, but the communication stops soon

"

read: 192 192 192 192 128 128 128 128 128 128 128 128 1 1 192 192 192 192 192 192 128 128 128 128 1 1 192 192 192 192

read: 128 128 128 128 128 128 128 128 128 128 192 192 192 192

read: 

read:

read:

read: 

"

How can I reset SCI settings and FIFO buffer correctly?

  • Please follow the steps I laid out in this post for adding SCI to a Motorware project e2e.ti.com/.../2078355

    Make sure you initialize the correct SCI port that can be used for UART terminal comms (I believe it's SCI-A, but you'll have to double check). You may also have to change jumper settings on the LaunchPad to route the SCI signals through the FTDI chip to reach your PC terminal

    Sean
  • I used SCI-A, and JAmper settings of S1 is 1-ON 2-ON 3-OFF.

    The problem occurs once in boot (turn on the Power Switch), after pushing reset button, I can use SCI correctly.
  • I am unable to answer why the SCI module is behaving this way for you, that area is not my expertise. I have successfully interfaced the SCI module to a Terminal program via the steps I gave above; additionally, adding FIFO capability and interrupt routine should be doable by following the steps given in the device TRM.

    I did take a look at the customer code that you mentioned, but nothing jumped out at me as to what could be the issue. If you would like, I can move this to the general C2000 forum and away from the motor control forum.

    Sean
  • I still can not solve the problem of SCI with InstaSPIN.
    Did you test SCI with boostxl module and Motor?
    Could you show us complete example codes?
  • For my example, I used project lab11a. All references to proj_lab11a are mutable based on which project you'd like to use.

    1) Add sci.c source file to your project, please ensure you link it correctly instead of copying it into your workspace. Follow the same process of Relative Addressing used in the lab. Right click on the project name, and select Properties->Resource->Linked Reources->Linked Resources tab to see how the other source files have been linked to

    2) Please ensure the sci.h file is on the include path. It should be by default. In the project, expand the "Includes" section and check that sw->drivers->sci->src->32b->f28x->f2806x is available through on of the include directory options

    3) Add SCI handle in HAL_init() function, which is called in proj_lab11a.c and instantiated in hal.c

    In HAL_init() add

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

    4) Add SCI initialization function in HAL_setParams() function, which is called in proj_lab11a.c and instantiated in hal.c

    In hal.h add

      extern void HAL_setupSciA(HAL_Handle handle);

    In hal.c add

      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 115200
        SCI_setBaudRate(obj->sciAHandle,(SCI_BaudRate_e)(0x0061));
        SCI_setPriority(obj->sciAHandle,SCI_Priority_FreeRun);
        SCI_enable(obj->sciAHandle);

        return;
        // end of HAL_setupSciA() function
    }


    **Change the function parameters as needed for your system

    In HAL_setParams() add

      HAL_setupSciA(handle);

    **I.e. call the function you just created

    3) Enable SCI-A peripheral clock

    In HAL_setupPeripheralClks(), located in hal.c, add

      CLK_enableSpiaClock(obj->clkHandle);

    4) Ensure GPIO settings are correct for SCI-A

    In HAL_setupGpios(), check which GPIO pins have been enabled as SCIATXDA and SCIRXDA.

      // UARTA RX
      GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_SCIRXDA);

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

    **I was using F2806x+BoostXL DRV8305, and these lines were already present in the HAL_setupGpios() function

    5) If you want an interrupt, instantiate a function such as: sciARxISR()

    6) Add your interrupt function to the interrupt vector table

    In HAL_initIntVectorTable(), located in hal.h, add

      pie->SCIRXINTA = &sciARxISR;

    7) Add a function call for enabling SCI interrupts. You can see a function in proj_lab11a.c called "HAL_enableAdcInts()." You'll want to model a function off of this one, but for SCI instead of ADC

    Add the declaration for HAL_enableSciInts() in hal.h similar to what you did above

    Add the instantiation of HAL_enableSciInts() in hal.c similar to what you did above

    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 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

    **function as I created on my end

    **Add HAL_enableSciInts() in proj_lab11a.c, i.e. call the function you just created.

    I highly recommend you change the ADC interrupt from CPU interrupt number 10 to CPU interrupt number 1 to avoid the SCI interrupt preempting your ADC interrupt (which is vital for FOC). My lab used a simple bit polling loop for the SCI (i.e. not interrupt driven) which was fine for my application.

    Please take the time to read the corresponding Technical Reference Manual on the SCI/UART module, as it describes the register structure, proper order to initialize your module, and other features such as the FIFO I didn't touch on. If you're going to use interrupts, also read that CPU Interrupt section as well, especially the PIE chart. You'll see that ADC1 can be assigned an HP designation (high priority); again, I recommend you use this one if you're going to use an interrupt driven SCI module

    Sean

  • Please use the above in conjunction with the guide I linked from the other E2E post above, as they are somewhat complementary (this goes into greater detail, other guide has a few line items that also need tending to)

    Sean
  • I read the Technical Reference Manual of SCI, and I modified the Priority of ADC1.

    I followed this thread and your comments,

    e2e.ti.com/.../2089647

    hal.c

    void HAL_enableAdcInts(HAL_Handle handle)

    {

     HAL_Obj *obj = (HAL_Obj *)handle;

     // enable the PIE interrupts associated with the ADC interrupts

     PIE_enableAdcInt(obj->pieHandle,ADC_IntNumber_1HP);

     // enable the ADC interrupts

     ADC_enableInt(obj->adcHandle,ADC_IntNumber_1);

     // enable the cpu interrupt for ADC interrupts

     CPU_enableInt(obj->cpuHandle,CPU_IntNumber_1);

     return;

    } // end of HAL_enableAdcInts() function

    hal.h

    static inline void HAL_initIntVectorTable(HAL_Handle handle)

    {

     HAL_Obj *obj = (HAL_Obj *)handle;

     PIE_Obj *pie = (PIE_Obj *)obj->pieHandle;

     ENABLE_PROTECTED_REGISTER_WRITE_MODE;

     pie->ADCINT1_HP = &mainISR;

     pie->SCIRXINTA = &sciarxISR;

     DISABLE_PROTECTED_REGISTER_WRITE_MODE;

     return;

    } // end of HAL_initIntVectorTable() function

    The modificated program works normally, but my first problem which is the initialization of SCI is not solved yet.

    So,,,, Then I have 2 questions.

    1. I found an old thread that discussed SCI initialization problem of Flash and RAM,

    e2e.ti.com/.../511522

    I think my problem is similar to this problem.

    Mr. Gudivada explains a solution, "You can avoid overflow by designing a good protocol between the transmitter and receiver making sure that the transmitter sends data only when the receiver acknowledges that the data is received."

    But I could not understood well this mention, would you please help us to understand?

    2. I also tried to use SCITX interrupt based on a MotorWare example of scia_loopback_interrupts.

    It works without motor, but motor not works. Because I already changed the priority of ADC1 to 1HP,  It seems that initialization fails. 

    How can I use SCITX interrupts with motor?

  • also this,
    hal.h
    static inline void HAL_acqAdcInt(HAL_Handle handle,const ADC_IntNumber_e intNumber)
    {
    HAL_Obj *obj = (HAL_Obj *)handle;

    // clear the ADC interrupt flag
    ADC_clearIntFlag(obj->adcHandle,intNumber);

    // Acknowledge interrupt from PIE group 10
    PIE_clearInt(obj->pieHandle,PIE_GroupNumber_1);

    return;
    } // end of HAL_acqAdcInt() function
  • In this function:

    void HAL_enableAdcInts(HAL_Handle handle)

    {

    HAL_Obj *obj = (HAL_Obj *)handle;

    // enable the PIE interrupts associated with the ADC interrupts

    PIE_enableAdcInt(obj->pieHandle,ADC_IntNumber_1HP);

    // enable the ADC interrupts

    ADC_enableInt(obj->adcHandle,ADC_IntNumber_1);

    // enable the cpu interrupt for ADC interrupts

    CPU_enableInt(obj->cpuHandle,CPU_IntNumber_1);

    return;

    } // end of HAL_enableAdcInts() function

    You must also change the enumeration for ADC_enableInt from "ADC_IntNumber_1" to "ADC_IntNumber_1HP"

  • Please check this your advice, ADC_IntNumber_1HP of ADC_enableInt occurs initialization fails.

    // enable the ADC interrupts
    ADC_enableInt(obj->adcHandle,ADC_IntNumber_1);
    You must also change the enumeration for ADC_enableInt from "ADC_IntNumber_1" to "ADC_IntNumber_1HP"

    In this thread,
    e2e.ti.com/.../1188229
    Maria said "But please call HAL_acqAdcInt(halHandle,ADC_IntNumber_1); instead of HAL_acqAdcInt(halHandle,ADC_IntNumber_1HP);"

    In my understanding, in order to enable ADC High Priority,
    I have to associate ADC_IntNumber_1HP of Interrupt to ADC_IntNumber1 of ADC flag.
    Is it a missunderstanding?
  • Looking at the ADC_enableInt() function, it actually doesn't matter if you use the _HP enum or not, as the function casts it to the same value as the non-HP enum
  • I use Motorware v17 and BOOSTXL-DRV8305EVM and LAUNCHXL-F28027F also LAUNCHXL-F28069M.

    Which version of Motorware did you use?

    I could not found the casts. I confuse.

    in adc.h, ADC_IntNumber _1= 0, ADC_IntNumber_1HP = 9

    //! \brief Enumeration to define the analog-to-digital converter (ADC) interrupt number

    //!

    typedef enum

    {

     ADC_IntNumber_1=0,        //!< Denotes ADCINT1

     ADC_IntNumber_2,          //!< Denotes ADCINT2

     ADC_IntNumber_3,          //!< Denotes ADCINT3

     ADC_IntNumber_4,          //!< Denotes ADCINT4

     ADC_IntNumber_5,          //!< Denotes ADCINT5

     ADC_IntNumber_6,          //!< Denotes ADCINT6

     ADC_IntNumber_7,          //!< Denotes ADCINT7

     ADC_IntNumber_8,          //!< Denotes ADCINT8

     ADC_IntNumber_9,          //!< Denotes ADCINT9

     ADC_IntNumber_1HP,        //!< Denotes ADCINT1 High Priority for use with PIE_enableAdcInt() only

     ADC_IntNumber_2HP,        //!< Denotes ADCINT2 High Priority for use with PIE_enableAdcInt() only

     ADC_IntNumber_9HP=0xE     //!< Denotes ADCINT9 High Priority for use with PIE_enableAdcInt() only

    } ADC_IntNumber_e;

    in adc.c

    void ADC_enableInt(ADC_Handle adcHandle,const ADC_IntNumber_e intNumber)

    {

     ADC_Obj *adc = (ADC_Obj *)adcHandle;

     uint_least8_t regNumber = intNumber >> 1;

     uint_least8_t lShift = ADC_INTSELxNy_NUMBITS_PER_REG - (((intNumber+1) & 0x1) << ADC_INTSELxNy_LOG2_NUMBITS_PER_REG);

     uint16_t setValue = ADC_INTSELxNy_INTE_BITS << lShift;

     ENABLE_PROTECTED_REGISTER_WRITE_MODE;

     // set the value

     adc->INTSELxNy[regNumber] |= setValue;

     DISABLE_PROTECTED_REGISTER_WRITE_MODE;

     return;

    } // end of ADC_enableInt() function

    levelshift gives,

    0b00000000 >> 1 = 0b00000000,

    0b00001001 >> 1 = 0b00000100

  • You are correct, looking back I had added lines of code on my version of adc.c that look like this:

    void ADC_enableInt(ADC_Handle adcHandle,const ADC_IntNumber_e intNumber)

    {

     uint16_t newIntNumber = intNumber;

     if(intNumber == ADC_IntNumber_1HP || intNumber == ADC_IntNumber_2HP)

     {

     newIntNumber -= 9;

     }

     ADC_Obj *adc = (ADC_Obj *)adcHandle;

     uint_least8_t regNumber = newIntNumber >> 1;

     uint_least8_t lShift = ADC_INTSELxNy_NUMBITS_PER_REG - (((newIntNumber+1) & 0x1) << ADC_INTSELxNy_LOG2_NUMBITS_PER_REG);

     uint16_t setValue = ADC_INTSELxNy_INTE_BITS << lShift;

     ENABLE_PROTECTED_REGISTER_WRITE_MODE;

     // set the value

     adc->INTSELxNy[regNumber] |= setValue;

     DISABLE_PROTECTED_REGISTER_WRITE_MODE;

     return;

    }

    You should just leave your enum as ADC_IntNumber_1.

    If you're having issues getting the motor to spin while you have an SPI interrupt enabled, we need to check if you're entering the mainISR or not. Have you put a debug point or counter in the routine to see if you are entering the ISR?

    Sean

  • I see, OK.

    > If you're having issues getting the motor to spin while you have an SPI interrupt enabled, we need to check if you're entering the mainISR or not. Have you put a debug point or counter in the routine to see if you are entering the ISR?

    I did not check it expressly, but I remember that a potentiometer worked correctly. It is readed the value at mainISR.

    I understand that I have to check soon directly.
    But my launchxl-f28027f was broken by writting flush over 40 times. I broke 4 lauchxl-f28027f already, I don't have reserve.
    It will take some time...

    And I also try same code in LAUNCHXL-F28069M, I could not found problems.
    Initialization problem will occurs in LAUNCHXL-F28027F with when the power gaved from BOOSTXL-DRV8305EVM.
  • Am I understanding correctly that you are not seeing issues on the F28069 that you experienced on the F28027?

    Sean
  • Yes, I could not found same problem on the F28069.

    The initialization problem is happen on the F28027F only.
    settings
    1. I enabled the SCI using this examples. github.com/.../instaspin_foc-SCI-eCAP
    2. I removed JP1, JP2, JP3.
    3. I enabled Serial Switch, and Boot Switches are 1:ON, 2:ON, 3:OFF.
    4. I gave the power through BOOSTXL-DRV8305EVM, it was given +24V.
    5. I connected the PC and F28027F's usb port. I monitored the serial communication using terminal monotor software.

    execution
    1. I switched on the +24V power supply, f28027f and drv8305 are waked up, but not worked.
    2. Serial monitor received strange long texts.
    3. I pushed the RST(S2) switch of F28027F, the motor began to spin and serial monitor received correct texts.

    I would like to solve this problem in order to incorporate the driver to a system.