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.

CC3235SF: PWM and I2C interfering with each others

Part Number: CC3235SF
Other Parts Discussed in Thread: SYSCONFIG, CC3220SF, DRV8850

Hi,

In my design, I am using 2 PWMs and I2C master.

I2C and PWM both work as expected individually. Trouble occurs when I enable 2nd PWM.

After I call PWM_open() for 2nd PWM, I2C_open() return with success but I2C_transfer() always return with a failure.

I probed I2C pins there is no activity on the pins after i call PWM_open() and then I2C_transfer().

I have a feeling that somehow PWM is interfering with I2C registers of its PIN configuration.

Below is my setup:

PIN16--SCL

PIN17--SDA

PIN2--IN1H       Enabling PWM on this PIN is causing the issue.

PIN64--IN2H

When i try to debug in the register view. I am not able to read the registers.

I am using the older version of simple link SDK and not using sysconfig.

Below is the configuration of the pins from CC3220SF_LAUNCHXL.c and CC3220SF_LAUNCHXL.h files.

/*
* =============================== I2C ===============================
*/
#include <ti/drivers/I2C.h>
#include <ti/drivers/i2c/I2CCC32XX.h>

I2CCC32XX_Object i2cCC3220SObjects[CC3220SF_LAUNCHXL_I2CCOUNT];

const I2CCC32XX_HWAttrsV1 i2cCC3220SHWAttrs[CC3220SF_LAUNCHXL_I2CCOUNT] = {
{
.baseAddr = I2CA0_BASE,
.intNum = INT_I2CA0,
.intPriority = (~0),
.clkPin = I2CCC32XX_PIN_16_I2C_SCL,
.dataPin = I2CCC32XX_PIN_17_I2C_SDA
}
};

const I2C_Config I2C_config[CC3220SF_LAUNCHXL_I2CCOUNT] = {
{
.fxnTablePtr = &I2CCC32XX_fxnTable,
.object = &i2cCC3220SObjects[CC3220SF_LAUNCHXL_I2C0],
.hwAttrs = &i2cCC3220SHWAttrs[CC3220SF_LAUNCHXL_I2C0]
}
};

const uint_least8_t I2C_count = CC3220SF_LAUNCHXL_I2CCOUNT;

/*
* =============================== PWM ===============================
*/
#include <ti/drivers/PWM.h>
#include <ti/drivers/pwm/PWMTimerCC32XX.h>

#define CONFIG_PWM_COUNT 2

/*
* ======== pwmTimerCC32XXObjects ========
*/
PWMTimerCC32XX_Object pwmTimerCC32XXObjects[CONFIG_PWM_COUNT];

/*
* ======== pwmTimerCC32XXHWAttrs ========
*/
const PWMTimerCC32XX_HWAttrsV2 pwmTimerCC32XXHWAttrs[CONFIG_PWM_COUNT] = {
/* IN1H */
{
.pwmPin = PWMTimerCC32XX_PIN_02, /* 02 */
},
/* IN2H */
{
.pwmPin = PWMTimerCC32XX_PIN_64, /* 64 */
},
};

/*
* ======== PWM_config ========
*/
const PWM_Config PWM_config[CONFIG_PWM_COUNT] = {
/* IN1H */
{
.fxnTablePtr = &PWMTimerCC32XX_fxnTable,
.object = &pwmTimerCC32XXObjects[IN1H],
.hwAttrs = &pwmTimerCC32XXHWAttrs[IN1H]
},
/* IN2H */
{
.fxnTablePtr = &PWMTimerCC32XX_fxnTable,
.object = &pwmTimerCC32XXObjects[IN2H],
.hwAttrs = &pwmTimerCC32XXHWAttrs[IN2H]
},
};

const uint_least8_t IN1H_CONST = IN1H;
const uint_least8_t IN2H_CONST = IN2H;
const uint_least8_t PWM_count = CONFIG_PWM_COUNT;

/*!
* @def CC3220SF_LAUNCHXL_I2CName
* @brief Enum of I2C names on the CC3220SF_LAUNCHXL dev board
*/
typedef enum CC3220SF_LAUNCHXL_I2CName {
CC3220SF_LAUNCHXL_I2C0 = 0,

CC3220SF_LAUNCHXL_I2CCOUNT
} CC3220SF_LAUNCHXL_I2CName;

/*!
* @def CC3220SF_LAUNCHXL_PWMName
* @brief Enum of PWM names on the CC3220SF_LAUNCHXL dev board
*/
typedef enum CC3220SF_LAUNCHXL_PWMName {
IN1H = 0,
IN2H,

CC3220SF_LAUNCHXL_PWMCOUNT
} CC3220SF_LAUNCHXL_PWMName;

  • Hi Jitendra Singh,

    Are you calling Board_init() before starting your drivers? Pins 1 and 2 by default are set as I2C by the bootloader. Board_init() resets the pins at the beginning of your application so you can reassign those pins and the I2C peripheral.

    Best regards,

    Sarah

  • Hi Sarah,

    If I call functions in below order I2C stops working.

    Board_initGeneral();

    BIOS_start();

    PWM_init();

    then in case, I need to generate PWM I just call the below sequence when needed

    PWM_open();  

    PWM_start();

    PWM_setDuty();

    PWM_stop();

    PWM_close();

    If I call functions in below order things are working when LPDS is not enabled.

    Board_initGeneral();

    BIOS_start();

    PWM_init();

    PWM_open();    

    then in case i need to generate PWM i just call below sequence when needed

    PWM_start();

    PWM_setDuty();

    PWM_stop();

    But my use case is to enable LPDS. for that, I am following the below sequence.

    Board_initGeneral();

    BIOS_start();

    PWM_init();

    PWM_open();    

    then in case i need to generate PWM i just call below sequence when needed

    Power_disablePolicy();

    PWM_start();

    PWM_setDuty();

    PWM_stop();

    Power_enablePolicy();

    The last sequence results in random PWM duty cycle and sometimes hang condition when I call PWM_stop();

    I am capturing the PWM waveform for the last case, Will share it with you. By then can you verify I am following the correct sequence for LPDS.

    Regards

  • Hi Sarah,

    I think after calling Power_enablePolicy(). The PWM period that was set in PWM_open() is lost.

    PWM_Params params;
    PWM_Params_init(&params);
    params.dutyUnits = PWM_DUTY_US;
    params.dutyValue = 0;
    params.periodUnits = PWM_PERIOD_US;
    params.periodValue = DRV8850_PWM_PERIOD;
    params.idleLevel = 0;

    The expected period is 100micosecond. It is 100microsecond if Power_enablePolicy() is never called.

    But if I have called Power_enablePolicy() before the period update to 870micosecond.

    I am observing a hang condition also after i call PWM_stop();

  • Hi Jitendra,

    I have not seen that issue with PWM_open(). Can you share your power policy configuration? What SDK version are you using?

    Are you checking the return codes for PWM_open, _start, and _setDuty?

    Best regards,

    Sarah

  • Hi Sarah,

    Let me check the return code and share it with you.

    below is the power configuration.

    I am calling the below functions to Enable and disable LPDS. But i am making sure that after calling PWM_start() the controller does not go into LPDS before i call PWM_stop().

    Other than this, can you comment on the correct order of calling the functions. What is the difference between PWM_stop() and PWM_close()? and when to call them?

  • I have found a hack to get it working. But I am not satisfied with it.

    I am testing the code on SDK3.20.

    These are my observations:

    State1:: If i call PWM_close(). I2C stops working until i call PWM_open() again.

    To work with State1 i never called PWM_close(). I just call PWM_open() at the start. I am not sure how it will impact LPDS state.

    The above solution works only until I enable LPDS. After LPDS below situation occurs.

    State2:: If I do not call PWM_open() after waking from LPDS. The PWM configurations like period seem to get lost. I verified in scope that the period is now 800us which was set to 100us in PWM_open(). The PWM handle is still valid and i am able to set the PWM duty cycle correctly.

    Regards

    To work with the above state this is what I do:

    I keep PWM in an open state. Then after waking up from LPDS i do a PWM_close() and PWM_open again. This way the whole thing seems to work as expected.

  • Hi Jitendra Singh,

    For the differences between the different PWM APIs, please see the TI Drivers documentation in the SDK (docs/tidrivers folder).

    Let's try to resolve your I2C issue first. Can you share how you initialize and open your I2C instance? When does this happen with Board_initGeneral() and the PWM APIs?

    Best regards,

    Sarah

  • Hi Sarah,

    I am calling I2C in below order.

    Board_initGeneral();

    BIOS_start();

    I2C_init();

    I call  as_I2CResetBus(); function. I have provided more details below. It checks if there is a condition in which some I2C slave has pulled I2C lines low because of previous interrupted I2C operation.

    I2C_init();

    I2C_open();

    I2C_transfer();

    I2C_close();

    as_I2CResetBus()

    Config SDA as input. Check if SDA is low

    If SCL is low

    config SCL as GPIO output. Provide toggles on SCL line to let Slave release I2C line.

  • Hi Jitendra,

    I am working to recreate your issue, and I will provide an update by the end of the week.

    Are you able to share the source code of your project showing the initial issue?

    Best regards,

    Sarah

  • Hi Sarah,

    I can share a project with you which has this issue recreated privately.

  • Hi Jitendra,

    I was able to combine the I2C and PWM SDK examples, and the drivers worked as expected with your pin configurations.

    Are you using a LaunchPad or a custom board? I remembered that pins 16 and 17 are booted as TDO and TDI (4-wire JTAG) when SOP is 010. If you are running a debug session, have you switched to 2-wire SWD mode?

    /cfs-file/__key/communityserver-discussions-components-files/968/i2ctmp_5F00_CC3235SF_5F00_LAUNCHXL_5F00_tirtos_5F00_ccs.zip

    Best regards,

    Sarah