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.

CONTROLSUITE: I2C routine

Part Number: CONTROLSUITE
Other Parts Discussed in Thread: MOTORWARE, TMS320F28069F

Dear TI experts,

Our customers has query below;

1、 My goal is to use C2000 controlsuite I2C_ EEPROM routine experiment read EEPROM in I2C query mode
2、 There is no problem using the original routine to read EEPROM in interrupt mode, but there is a problem when disabling interrupt and reading EEPROM in query mode
Attach Code:
void I2CA_ Init(void)
{
I2caRegs. I2CSAR. all = I2C_ SLAVE_ ADDR;
I2caRegs. I2CPSC. all = 6;
I2caRegs. I2CCLKL = 10;
I2caRegs. I2CCLKH = 5;
I2caRegs. I2CMDR. all = 0x0020;
return;
}
Uint16 I2CA_ ReadData(struct I2CMSG *msg)
{
I2caregs I2CSAR = msg->SlaveAddress;
I2caRegs. I2CCNT = 2;
I2caRegs. I2CDXR = msg->MemoryHighAddr;
I2caRegs. I2CDXR = msg->MemoryLowAddr;
I2caRegs. I2CMDR. all = 0x2620;
DELAY_ US(500);
I2caRegs. I2CCNT = msg->NumOfBytes;
I2caRegs. I2CMDR. all = 0x2C20;
Uint16 i;
for(i = 0; i < msg->NumOfBytes; i++)
The{
while(!I2caRegs.I2CSTR.bit.RRDY);
*(msg->MsgBuffer + i) = I2caRegs. I2CDRR. all;
}
return I2C_ SUCCESS;
}
Note: FIFO is disabled by the program. Query is adopted. While running (! I2caregs. I2cstr. Bit. RRDY) enters an endless loop, and RRDY cannot always be 0. If it is initialized to FIFO mode, while (! I2caregs. I2cstr. Bit. RRDY) is changed to while (! I2caregs. I2cffrx. Bit. Rxffint) cannot clear rxffintw bit, and cannot read data normally.
Could  you tell me what the problem is? Thank you in advance.

Best Regards,
William

  • William, 

    Which device are you trying this on? 

    Instead of the lines starting from  "I2caRegs. I2CMDR. all = 0x2C20;" please try using the folllowing lines of code

    //
    // send Start condition
    //
    I2caRegs.I2CMDR.bit.STT = 0x1;

    //
    // Read the received data into RX buffer
    //

    Uint16 count =0;
    while(count < msg->NumOfBytes)
    {
        if(I2caRegs.I2CSTR.bit.RRDY ==0x1)
       {
         *(msg->MsgBuffer + count) = I2caRegs.I2CDRR.all;
          count++;
       }
    }

    //
    // Send STOP condition
    //
    I2caRegs.I2CMDR.bit.STP = 0x1;
    while(I2caRegs.I2CMDR.bit.STP != 0x0);

    Best Regards

    Siddharth

  • Dear Siddharth

    Customers use the way you advice and he has  two questions that need help.

    1、 If i2caregs is not set during initialization I2COAR = 0x0050; Unable to receive data. 

    2、 After reading a data from DRR (it is correct), RRDY is always 0 and cannot continue to read data. 

    thank you

    Best Regards,
    William

  • William,

    I2COAR is used to specify own address. Which slave address is it trying to communicate with? If it does not find any such address on the bus, then it won't receive the data. 

    RRDY should be set each time it receives a new data. Are you not observing this?

    Best Regards

    Siddharth

  • Dear Siddharth

    Thanks for your reply , our customers has still query below when he understand you reply before.

    As stated in the reply, if there is no error in sending the requested EEPROM information, the EEPROM should send the requested data bytes, the DRR register should be read a byte of data, and the EEPROM sends another byte of data until the requested CNT bytes are sent, and the internal CNT is reduced to 0. But when I first received a byte of data, the RRD was 1, and then it was always 0, indicating that the DRR received only one byte. I don't know why? On the other hand, I don't know why I have to set oar to receive data? Only one EEPROM is connected to my I2C bus. I don't think the reliability of I2C using query method is good. How about the reliability of analog GPIO? Can it be used in FOC project? Because I didn't make a mistake in this way.

    Thanks again.

    Best Regards,
    William

  • Hi Williams, 

    Request the customer to look at the I2C Status register I2CSTR register and see if anything is flagged.  I2COAR is used to set own address. Whenever an address is sent on the I2C bus , the own address is used to determine whether it is intended for the particular slave.  

    The RRDY bit should be set each time it receives a new data. What is the configuration in the I2CMDR register?

    Best Regards

    Siddharth

  • Hello Siddharth

    I have a new problem to be solved urgently! Tms320f28069f chip. The routine adopts motorware FOC hvkit lab10e. I hope to enable tz1-tz3 interrupt in epwm control. I modified Hal Void Hal in C_ Setupfaults (hal_handle), and the interrupt vector and interrupt function have been set. The code is as follows:

    void HAL_setupFaults(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
      uint_least8_t cnt;
      // Configure Trip Mechanism for the Motor control software
      // -Cycle by cycle trip on CPU halt
      // -One shot fault trip zone
      // These trips need to be repeated for EPWM1 ,2 & 3
          PWM_enableTripZoneSrc(obj->pwmHandle[0],
              PWM_TripZoneSrc_OneShot_TZ1_NOT);
          PWM_enableTripZoneSrc(obj->pwmHandle[1],
              PWM_TripZoneSrc_OneShot_TZ2_NOT);
          PWM_enableTripZoneSrc(obj->pwmHandle[2],
              PWM_TripZoneSrc_OneShot_TZ3_NOT);
          for (cnt = 0; cnt < 3; cnt++)
          {
              PWM_setTripZoneState_TZA(obj->pwmHandle[cnt],
                                       PWM_TripZoneState_EPWM_Low);
              PWM_setTripZoneState_TZB(obj->pwmHandle[cnt],
                                       PWM_TripZoneState_EPWM_Low);
          }
      // For testing TZ int
      // enable the PIE interrupts associated with the ADC interrupts
          PIE_enablePwmTzInt(obj->pieHandle,PWM_Number_1);
      // enable the Tz interrupts
          PWM_enableTripZoneInt(obj->pwmHandle[PWM_Number_1], PWM_TripZoneFlag_OST);
      // enable the cpu interrupt for EPWM1_TzINT
          CPU_enableInt(obj->cpuHandle, CPU_IntNumber_2);
          return;
    } // end of HAL_setupFaults() function,in here,only enable Tz1 to test


    The routine has called Hal in main()_ setupFaults(). I found a strange phenomenon: when running the program, immediately enter the Tz interrupt program, after examination, found in main () middle note.
    HAL_ Hal is called when setparams()_ When setparams(), PWM - > tzfrc | = PWM_ TZFRC_ OST_ BITS; Make tzflg = 0x4 and generate a software mandatory event. I don't understand what this means. What should I do to enable tz1-tz3 normally? Wait for your reply!

    Continue to do the epwm TZ interrupt experiment. After entering the interrupt, clear the interrupt, exit the interrupt, enter the interrupt again, and keep reciprocating. I read the state of gpio12-14 in GPIO mode to determine that it is a high-level state, and check it with the instrument. Why can't I clear the interrupt and generate repeated entry interrupt? Here is my interrupt function code:

    interrupt void igbtTz1ISR(void)
    {
    Temp_count ++;
    // HAL_tzClearFlag(halHandle, PWM_Number_1, PWM_TripZoneFlag_Global);
    // HAL_tzClearFlag(halHandle, PWM_Number_1, PWM_TripZoneFlag_CBC);
    HAL_tzClearFlag(halHandle, PWM_Number_1, PWM_TripZoneFlag_OST);
    HAL_tzClearFlag(halHandle, PWM_Number_1, PWM_TripZoneFlag_Global);
    HAL_pieAckInt(halHandle, PIE_GroupNumber_2);

    return;
    }

    Thank you.

    Best Regards,
    William

  • William, 

    Will forward your query to PWM expert.

    Best Regards

    Siddharth

  • You may check if the bits of the TZFLG register of EPWM module are set/clear after the related actions. If not, check if the input signals on TZ pins and the function you used are correct. 

    HAL_tzClearFlag(halHandle, PWM_Number_1, PWM_TripZoneFlag_OST);
    HAL_tzClearFlag(halHandle, PWM_Number_1, PWM_TripZoneFlag_Global);

     Or refer to the function code below.

    //! \brief Clears the pulse width modulation (PWM) trip flag
    //! \param[in] pwmHandle The pulse width modulation (PWM) object handle
    static inline void PWM_clearTzTrip(PWM_Handle pwmHandle)
    {
    PWM_Obj *pwm = (PWM_Obj *)pwmHandle;


    ENABLE_PROTECTED_REGISTER_WRITE_MODE;

    // set the bits
    pwm->TZCLR = (PWM_TZCLR_OST_BITS | PWM_TZCLR_CBC_BITS | PWM_TZCLR_INT_BITS);

    DISABLE_PROTECTED_REGISTER_WRITE_MODE;

    return;
    } // end of PWM_clearTzTrip() function

  • Dear TI 

    Thank you very much for your great support and also thanks to TI Technology for the reply. But this still doesn't solve my problem. Calling HAL_tzClearFlag() in my interrupt function also calls PWM_clearTripZone(); modify this function according to the scheme proposed by TI technology, the code is as follows:
    void PWM_clearTripZone(PWM_Handle pwmHandle, const PWM_TripZoneFlag_e tripZoneFlag)
    {
    PWM_Obj *pwm = (PWM_Obj *)pwmHandle; ENABLE_PROTECTED_REGISTER_WRITE_MODE;
    // set the bits
    // pwm->TZCLR |= tripZoneFlag;
    pwm->TZCLR = (PWM_TZCLR_OST_BITS | PWM_TZCLR_CBC_BITS | PWM_TZCLR_INT_BITS); DISABLE_PROTECTED_REGISTER_WRITE_MODE; return;
    } // end of PWM_clearTripZone() function
    After testing, the Tz interrupt is still being entered frequently.
    Register state during test:
    1 Use breakpoints to check that TZFLG is 0x5 when entering an interrupt, and 0x0 when exiting an interrupt
    TZSEL=0x0100
    TZCTL = 0x000A
    TZEINT=0x4
    ETSEL=0x0900
    ETPS=0x0101
    ETFLG=0x4

    It means that the TZ configuration is correct and the data feedback is correct, but a new interrupt is generated immediately after exiting the interrupt, TZFLG= 0x5, indicating that an interrupt event has occurred. TZFLG=0x4 of pwm2/pwm3 (because TZ2 and TZ3 are set during initialization), but no interrupt is generated, indicating that pwm2/pwm3 also generated OST events. CMPCTL is always changing. In addition, an experiment was done to verify the possible problems with the TZ1 pin, set TZ1 (GPIO12) to XINT1, it can normally generate interrupts, and will not enter interrupts frequently, therefore, the pin problem can be ruled out. TZ frequently goes into the possibility of interruptions.
    In view of the above situation, it means that the event is really triggered. In addition to the TZ1/2/3 pin triggering of the TZ event, there is also a DC (digital comparator) and Force that can be triggered. I don't know if the DC can be turned off, it will generate a normal pwm signal. Affect?

    Best Regards,
    William

  • It's better to wait some time to enable the TZ interrupt again after the TZ pin is high, or only enable the TZ again when try to start the PWM output. It seems like the TZ input is still low to trigger the TZ interrupt when you clear the TZFLAG to enable the TZ interrupt again.