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 timer32/clocking issue

Hello,

I am using the MSP-EXP432P401R development kit, and have issues trying to set up the Timer32 module.

I would like to have an interrupt generated each 20.8µs (48kHz), so i set up Timer32 in periodic mode with a reload value of 1000.

I am toggling a pin in the interrupt to verify the generated frequency. Surprisingly, my scope shows it as a 2.5kHz square wave whereas it should be a 24kHz square wave !

I also used the CS_getMCLK() function from the DriverLib API, which returns 128kHz in debug mode. I would expect it to return 48MHz ...

Here is my code :

/** SONIC DISASTER **
** David BLANCHARD **

** RELEASE NOTES
	28/06/2016 : first version
**/


/* DriverLib Includes */
#include "driverlib.h"

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>

/** Interrupt routines declaration **/
void ADC_interrupt();
void TimerA_interrupt();

int main(void)
{
	uint32_t MCLK_freq;

	/* Stop interrupts for initialisation */
	Interrupt_disableMaster();

    /* Stop Watchdog  */
    MAP_WDT_A_holdTimer();

    /* Power */
    PCM_setPowerState(PCM_AM_LDO_VCORE1);

    /* Clocking */
    //Crystal inputs
    GPIO_setAsInputPin(GPIO_PORT_PJ, GPIO_PIN2);
    GPIO_setAsOutputPin(GPIO_PORT_PJ, GPIO_PIN3);
    CS_setExternalClockSourceFrequency(32000,48000000);
    CS_setReferenceOscillatorFrequency(CS_REFO_128KHZ);
    CS_enableClockRequest(CS_ACLK);
    CS_enableClockRequest(CS_MCLK);
    CS_enableClockRequest(CS_HSMCLK);
    CS_enableClockRequest(CS_SMCLK);
    CS_startHFXT(false);
    CS_startLFXTWithTimeout(CS_LFXT_DRIVE3, 10);
    CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    CS_initClockSignal(CS_HSMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    CS_initClockSignal(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    CS_initClockSignal(CS_BCLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);


    /* Init Timer 48kHz */
    Timer32_initModule(TIMER32_0_BASE, TIMER32_PRESCALER_1, TIMER32_1_MODULE6BIT, TIMER32_PERIODIC_MODE);
    Timer32_setCount(TIMER32_0_BASE, 1000);
    Timer32_enableInterrupt(TIMER32_0_BASE);
    Timer32_registerInterrupt(TIMER32_0_INTERRUPT, ADC_interrupt);
    Timer32_startTimer(TIMER32_0_BASE, false);


    /* DEBUG - GPIO setup */
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN5);
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN6);


    CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);

    /* Interrupts activation */
    Interrupt_enableMaster();

    /* Main program loop */
    while(1)
    {
    	MCLK_freq=CS_getMCLK();
    }
}

/** Interrupt routines */
/* ADC 48kHz interrupt */
void ADC_interrupt()
{
	//DEBUG --> write f/2 square wave to output
	GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN6);
	Timer32_clearInterruptFlag(TIMER32_0_BASE);
}

I desperately searched for hours, any help would be apreciated !

Thank you in advance,

David

  • Hello David,

    From the looks of things you seem to have setup your clocks fine. Although I am unsure as to why you set MCLK twice. If you are seeing MCLK as 128kHz, that's the same frequency as what you set REFO. Is your HFXTAL attached and running properly? I would place a breakpoint during your main loop to check clock settings and possible Oscillator Fault flags in the register view of CCS to see if there are any errors.

    Also for Timer output, using an interrupt approach to output a GPIO could change your output frequency (slow it down) for the CPU has to get involved and change tasks. If the CPU is fast enough compared to the output frequency, this isn't much of a problem. However, there is a better way to do this by letting the Timer_A module output your desired square wave for you. Since you are only counting to 1k anyway, you do not need to use the Timer32 module. The Timer_A CC registers have corresponding output pins that you can output a desired square wave on by changing the output modes of the timer. This should give you more flexibility here.
  • David,

    Did this suggestion help out your issue?
  • Hello Jace,

    Thank you for your answer. I placed a breakpoint in the main loop as you recommended, and figured out that the MCLK clock didn't initialize properly. The actual problem was the GPIOs setup, I had to set them as peripheral output pins whereas I configured them as regular input/output pins.

    Here is the solution:

    int main(void)
    {
    	uint32_t MCLK_freq;
    
    	/* Stop interrupts for initialisation */
    	Interrupt_disableMaster();
    
    	/* Halting the Watchdog */
    	MAP_WDT_A_holdTimer();
    
    	/* Pins I/O configuration */
    	//Clock
    	MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,GPIO_PIN3 | GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);
    	//Debug probes
    	MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN5);
    	MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN6);
    
    	/* Setting the external clock frequency */
    	CS_setExternalClockSourceFrequency(32000,48000000);
    
    	/* Starting HFXT in non-bypass mode without a timeout. Before we start
    	 * we have to change VCORE to 1 to support the 48MHz frequency */
    	MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
    	MAP_FlashCtl_setWaitState(FLASH_BANK0, 2);
    	MAP_FlashCtl_setWaitState(FLASH_BANK1, 2);
    	CS_startHFXT(false);
    
    	/* Initializing MCLK to HFXT (effectively 48MHz) */
    	MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
        /* Init Timer 48kHz */
        Timer32_initModule(TIMER32_0_BASE, TIMER32_PRESCALER_1, TIMER32_1_MODULE6BIT, TIMER32_PERIODIC_MODE);
        Timer32_setCount(TIMER32_0_BASE, 1000);
        Timer32_enableInterrupt(TIMER32_0_BASE);
        Timer32_registerInterrupt(TIMER32_0_INTERRUPT, ADC_interrupt);
        Timer32_startTimer(TIMER32_0_BASE, false);
    
        /* Interrupts activation */
        Interrupt_enableMaster();
    
        /* Main program loop */
        while(1)
        {
        	MCLK_freq=CS_getMCLK();
        }
    }

    Jace H said:
    Hello David,
    Also for Timer output, using an interrupt approach to output a GPIO could change your output frequency (slow it down) for the CPU has to get involved and change tasks. If the CPU is fast enough compared to the output frequency, this isn't much of a problem. However, there is a better way to do this by letting the Timer_A module output your desired square wave for you. Since you are only counting to 1k anyway, you do not need to use the Timer32 module. The Timer_A CC registers have corresponding output pins that you can output a desired square wave on by changing the output modes of the timer. This should give you more flexibility here.

    My final goal is not to generate a square ware, it is just for testing purposes. I'd like to run the sampling subroutine at 48kHz (which works now).

    Thank you for everything !

    David

**Attention** This is a public forum