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.
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 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