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.

CCS/MSP432P401R: GPIO toggle frequency to Timer32

Part Number: MSP432P401R

Tool/software: Code Composer Studio

Hi All, 

My goal was to generate an output on Pin P6.7 with a frequency at 500kHz. However, after many attempts of changing some parameters, I can only get a maximum frequency at around 268kHz. How would I go about correcting this?

 This is my first time coming back to the MSP432 after a year break so I have gotten rusty; I tried reviewing datasheets and manuals but am still stuck. (And also my first post here)

/*
 * MSP432 GPIO - Pin 6.7 with Timer32_0
 *
 */

#include <stdint.h>  //Exact-width integer types
#include <ti\devices\msp432p4xx\driverlib\driverlib.h>  //Driver library


#define DCO_FREQ    48e6  //unit: Hz; DCO nominal frequencies: 1.5, 3, 6, 12, 24, 48 MHz.
#define TIMER0_FREQ   500000  //unit: Hz


//function prototypes
void initDevice(void);
void initTimer(void);
void initGPIO(void);


//global variables
uint32_t clockMCLK;


void main(void)
{
    initDevice();
    initTimer();
    initGPIO();


    //Enable interrupts
    Interrupt_enableSleepOnIsrExit();
    Interrupt_enableMaster();

    Timer32_startTimer(TIMER32_0_BASE, false);

    while(1)
    {
        PCM_gotoLPM0();
    }

}


void initDevice(void)
{
    WDT_A_holdTimer();  //stop Watchdog timer

    //Change VCORE to 1 to support a frequency higher than 24MHz.
    //See data sheet for Flash wait-state requirement for a given frequency.
    PCM_setPowerState(PCM_AM_LDO_VCORE1);
    FlashCtl_setWaitState(FLASH_BANK0, 1);
    FlashCtl_setWaitState(FLASH_BANK1, 1);

    //Enable FPU for DCO Frequency calculation.
    FPU_enableModule();
    FPU_enableLazyStacking(); // Required to use FPU within ISR.

    //Only use DCO nominal frequencies: 1.5, 3, 6, 12, 24, 48MHz.
    CS_setDCOFrequency(DCO_FREQ);

    //Divider: 1, 2, 4, 8, 16, 32, 64, or 128.
    //SMCLK used by UART and ADC14.
    CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_8);
    CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_16);

    clockMCLK = CS_getMCLK();
}


void initTimer(void)
{
    Timer32_initModule(TIMER32_0_BASE, TIMER32_PRESCALER_1, TIMER32_32BIT, TIMER32_PERIODIC_MODE);
    Timer32_setCount(TIMER32_0_BASE, clockMCLK/TIMER0_FREQ - 1);
    Timer32_enableInterrupt(TIMER32_0_BASE);
    Interrupt_enableInterrupt(INT_T32_INT1); //Enable Timer32_0 interrupt in the interrupt controller.
}


void initGPIO(void)
{
    //Configure P6.7 as output.
    GPIO_setAsOutputPin(GPIO_PORT_P6, GPIO_PIN7);
}


//Timer32_0 ISR
void T32_INT1_IRQHandler(void)
{
    Timer32_clearInterruptFlag(TIMER32_0_BASE);
    GPIO_toggleOutputOnPin(GPIO_PORT_P6, GPIO_PIN7);
}


Any insight would be much appreciated. 

Regards, 

Jenna

  • With an interrupt rate of 500k/second, and each interrupt (toggle) generating half a cycle, that's 250kHz. That's what I see on my scope.

    If generating a 500kHz square wave is your goal, I notice that P6.7 can also output TA2.4, which will probably be a steadier signal than one generated by software. [Ref data sheet (SLAS826G) Table 6-77.]

    [Edit: It occurred to me later that what you were describing was increasing the interrupt rate from the 500k in that source file and not succeeding. I can't tell you exactly how long that ISR takes, but >48 clocks wouldn't surprise me. And the optimizer can't do much with it. I still think TA2.4 is your best bet.]

    [Edit: Actually I can tell you how long the ISR takes: 48000k/(268k*2) or about 90 clocks.]

  • Here is a pwm example:

    Also, something to bear in mind is that there is that there are additional clock cycles associated with the toggling of the IO.  See table 5.25.2.

  • Yes, I'm getting right around 250kHz with the TIMER0_FREQ set to 500k, which shows each toggle at half a cycle like you mentioned. However, if I set the TIMER0_FREQ to 1M, half would be the desired 500k, but I only can see 268k on the scope. 

    I'm not sure I completely follow about the TA2.4 or the ISR time. I see what you're talking about in the data sheet, but not sure how to implement that after further reading. How would I go about outputting TA2.4? 

  • If you look at the attached example in the earlier post you are going to move from TA0.1 on P2.4 to TA2.4 on P6.7. This means that in the PWM definition you use capture-compare register 4 instead of 1 (line 68). The GPIO being set to primary output function is on port 6 pin 7 instead of port 2 pin 4 (line 89). And the timer base will be changed to TIMER_A2_BASE (lines 97 and 127).

    Regards,
    Chris
  • That makes sense. The pwm route is a good way to go. I just modified what you mentioned then changed some of the clocking to allow the 500kHz output like I wanted while staying within the tech ref doc parameters. Thank you for the quick replies and all your help!

**Attention** This is a public forum