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.

MSP432P401R: Simultaneous PWM and I2C

Part Number: MSP432P401R


Hello,

For some reason, it seems that it is not possible to perform I2C communication and run a PWM at the same time, even if the pins are different. Whenever the PWM starts running, the I2C communication reads an incorrect value and then fails afterwards. Please see attached code. The I2C module is EUSCI_B0, and the PWM is running on Timer A0. Any help would be greatly appreciated!

#include "msp.h"
#include "stdio.h"
#include "driverlib.h"

#define CLKFRQ 3000000
#define SlaveAddress 0x48
#define T 1
#define initTime 5     //
#define BUFSIZE 512
#define PWMCTGT 3000

void i2cTransmitMBStart(char);
char i2cReceiveMBStop();
void initPWM();
void setPWM(float);

const eUSCI_I2C_MasterConfig i2cConfig = {
    EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
    CLKFRQ, // SMCLK = 3MHz
    100000, // Desired I2C Clock of 100khz
    0, // No byte counter threshold
    EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};

const Timer_A_UpModeConfig upConfig = {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_64,
    T * CLKFRQ / 64,
    TIMER_A_TAIE_INTERRUPT_DISABLE,
    TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE,
    TIMER_A_DO_CLEAR
};

Timer_A_PWMConfig pwmConfig0 = {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_1,
    PWMCTGT,
    TIMER_A_CAPTURECOMPARE_REGISTER_1,
    TIMER_A_OUTPUTMODE_RESET_SET,
    0
};

Timer_A_PWMConfig pwmConfig1 = {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_1,
    PWMCTGT,
    TIMER_A_CAPTURECOMPARE_REGISTER_1,
    TIMER_A_OUTPUTMODE_RESET_SET,
    0 * PWMCTGT
};


int cnt = 0;
float dc = 0.5;
char temps[BUFSIZE];
char sem = 0;

/**
 * main.c
 */
void main(void)
{
    WDT_A -> CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;   //stop watchdog timer
    CS_setDCOFrequency(CLKFRQ);
    CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);

    // initialize the I2C master
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN5, GPIO_PRIMARY_MODULE_FUNCTION);
    I2C_initMaster(EUSCI_B1_BASE, &i2cConfig);
    I2C_setSlaveAddress(EUSCI_B1_BASE, SlaveAddress);
    I2C_enableModule(EUSCI_B1_BASE);
//    I2C_clearInterruptFlag(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT2 | EUSCI_B_I2C_NAK_INTERRUPT);
//    I2C_enableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT2 | EUSCI_B_I2C_NAK_INTERRUPT);
//    Interrupt_setPriority(INT_EUSCIB1, 0x20);
//    Interrupt_disableInterrupt(INT_EUSCIB1);    //initially disabled

//    initPWM();
//    setPWM(0.0);    //no control at first
    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);
    Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig0);

    // setup Timer A
    CS_setDCOFrequency(CLKFRQ);
    CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    Timer_A_configureUpMode(TIMER_A3_BASE, &upConfig);  //configure Timer A using above struct
    Timer_A_startCounter(TIMER_A3_BASE, TIMER_A_UP_MODE);   //start Timer A
//    Interrupt_setPriority(INT_TA3_0, 0x40);
    Interrupt_enableInterrupt(INT_TA3_0);

    for(; ; ) {}
    // return;
}

void TA3_0_IRQHandler() {
//    Interrupt_enableInterrupt(INT_EUSCIB1);
    if (!sem) {     //need to write to temperature register
        I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
        I2C_masterSendSingleByte(EUSCI_B1_BASE, 0x00);
        printf("Time\tTemp\n");
        sem = 1;
    }

    I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_RECEIVE_MODE);
    temps[cnt] = I2C_masterReceiveSingleByte(EUSCI_B1_BASE);
    printf("%d\t%d\n", cnt, temps[cnt]);
//    Interrupt_disableInterrupt(INT_EUSCIB1);

    Timer_A_clearCaptureCompareInterrupt(TIMER_A3_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);
    cnt++;
    if (cnt == initTime) {
//        setPWM(dc);
        Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig1);
    }

    if (cnt == BUFSIZE) {
        Interrupt_disableInterrupt(INT_TA3_0);
    }

    return;
}

void initPWM() {
    P2DIR = (P2DIR) | 0x10;     //set Pin 2.4 as output
    TA0CCR0 = PWMCTGT;
    TA0CCTL1 = OUTMOD_7;
    TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;
    return;
}

void setPWM(float dutyCycle) {
    P2SEL0 = (P2SEL0) | 0x10;
    P2SEL1 = (P2SEL1 & ~0x10);
    TA0CCR1 = dutyCycle * PWMCTGT;
    return;
}

**Attention** This is a public forum