Part Number: MSP432P401R
TI Devs,
This may be something basic I have just missed in combing over the Datasheet, Driverlib User's Guide and Tech Reference. I have a simple ADC14 example that uses a potentiometer on a breadboard feeding the input back to the MSP432 on P5.5 that is then used to set CCR1 compare value on TIMER_AO setting the PWM that controls the P2.0 red LED. Works perfectly, but I adjust +5 on the ADC result to ensure CCR1 is set to CCR0 + 1 to fully turn the LED off. To add to this example I wanted to use Switch1 and Switch2 (P1.1 and 1.4) to turn the TIMER_A0 PWM on/off either by stop/starting TIMER_A0 or by setting CCR1 to CCR0 + 1.
The problem is this. When the ADC interrupt is active (INT_ADC14) the interrupt for PORT1 (INT_PORT1) will not fire. (I added output on the P1.0 LED just to have a simple visual). If I don't enable INT_ADC14 until I'm within INT_PORT1, it fires just fine the first time and then doesn't fire after INT_ADC14 is enabled. That leads me to believe I have either overlooked some constraint on how ADC operates, or there is something funny on input with P5.5 (default pin for A0) which shows "reserved" next to the pinout in the User's Guide diagram??
The code is minimal and is included below:
#include <ti/devices/msp432p4xx/driverlib/driverlib.h> #include <stdint.h> #include <stdbool.h> #define TA0_PWMPERIOD 0x7f /* 127 */ #define TA0_DUTYCYCLE 0x3f /* 63 */ static volatile uint16_t adcResult; static volatile uint16_t adcPWMPeriod; /* TimerA0 UpMode Configuration Parameter for PWM */ Timer_A_UpModeConfig TimerA0_PWMConfig = { TIMER_A_CLOCKSOURCE_ACLK, /* clockSource */ TIMER_A_CLOCKSOURCE_DIVIDER_1, /* clockSourceDivider */ TA0_PWMPERIOD, /* timerPeriod */ TIMER_A_TAIE_INTERRUPT_DISABLE, /* timerInterruptEnable_TAIE */ TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, /* captureCompareInterruptEnable_CCR0_CCIE */ TIMER_A_DO_CLEAR /* timerClear */ }; /* TimerA0 PWM with CCR1 */ Timer_A_CompareModeConfig compareConfigA01 = { TIMER_A_CAPTURECOMPARE_REGISTER_1, /* compareRegister */ TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE, /* compareInterruptEnable */ TIMER_A_OUTPUTMODE_TOGGLE_RESET, /* compareOutputMode */ TA0_DUTYCYCLE /* compareOutputMode */ }; /* Port mapper configuration register (See Table 13-1 Tech Reference, Pg 702) * Timer_A0 CCR1 mapped to take the PWM output for the RGB LED (red) and P2.4. */ const uint8_t port_mapping[] = { PM_TA0CCR1A, PM_NONE, PM_NONE, PM_NONE, PM_NONE, PM_NONE, PM_NONE, PM_NONE }; int main(void) { /* Stop Watchdog */ MAP_WDT_A_holdTimer(); /* Enabling the FPU for floating point operation */ MAP_FPU_enableModule(); MAP_FPU_enableLazyStacking(); /** NOTE * With adc and P5.5 as input all other interrupts disabled while INT_ADC14 * is enabled. */ /* Configuring P1.0 as output (trend temp increasing - on / decreasing - blinking) */ MAP_GPIO_setAsOutputPin (GPIO_PORT_P1, GPIO_PIN0); MAP_GPIO_setOutputLowOnPin (GPIO_PORT_P1, GPIO_PIN0); /* Configure P1.1 (switch_1) and P1.4 (switch2) as input with pull-up */ MAP_GPIO_clearInterruptFlag (GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4); MAP_GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4); /* Configure Port1 Interrupt for both Pin1 and Pin4 and enable interrupt */ MAP_GPIO_enableInterrupt (GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4); MAP_Interrupt_enableInterrupt (INT_PORT1); /* Initialize main clock to 3MHz */ MAP_CS_setDCOCenteredFrequency (CS_DCO_FREQUENCY_3); /* Remapping TA1CCR1 output pin to P2.0 (red LED of LED2) and P2.4 PWM */ MAP_PMAP_configurePorts ((const uint8_t *) port_mapping, PMAP_P2MAP, 1, PMAP_DISABLE_RECONFIGURATION); /* Set pin P2.0 as output pin */ MAP_GPIO_setAsPeripheralModuleFunctionOutputPin (GPIO_PORT_P2, GPIO_PIN0, GPIO_PRIMARY_MODULE_FUNCTION); /* start PWM on TimerA_0 with CCR0 & CCR1 interrupts enabled */ MAP_Timer_A_configureUpMode (TIMER_A0_BASE, &TimerA0_PWMConfig); MAP_Timer_A_initCompare (TIMER_A0_BASE, &compareConfigA01); /* Initializing ADC (MCLK/1/1) with temperature sensor routed */ MAP_ADC14_enableModule(); MAP_ADC14_initModule (ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, ADC_NOROUTE); /* Setting up GPIO pins as analog inputs (and references) */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin (GPIO_PORT_P5, GPIO_PIN5, GPIO_TERTIARY_MODULE_FUNCTION); /* Configuring ADC Memory (ADC_MEM0 and 3.3v reference) in repeat * mode). */ MAP_ADC14_configureSingleSampleMode (ADC_MEM0, true); MAP_ADC14_configureConversionMemory (ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A0, ADC_NONDIFFERENTIAL_INPUTS); /* Configuring the sample/hold time for 192 (default 4) */ // MAP_ADC14_setSampleHoldTime (ADC_PULSE_WIDTH_192,ADC_PULSE_WIDTH_192); /* Enabling sample timer in auto iteration mode and interrupts*/ MAP_ADC14_enableSampleTimer (ADC_AUTOMATIC_ITERATION); MAP_ADC14_enableInterrupt (ADC_INT0); MAP_Interrupt_enableInterrupt (INT_ADC14); MAP_Interrupt_enableSleepOnIsrExit(); MAP_Interrupt_enableMaster(); /* Starting the Timer_A0 in up mode generatig PWM */ MAP_Timer_A_startCounter (TIMER_A0_BASE, TIMER_A_UP_MODE); /* Triggering the start of the sample */ MAP_ADC14_enableConversion(); MAP_ADC14_toggleConversionTrigger(); while(1) { // MAP_PCM_gotoLPM0(); MAP_PCM_gotoLPM3(); } } /** This interrupt happens whenever a conversion has been completed and placed * into ADC_MEM0. */ void ADC14_IRQHandler(void) { uint64_t status; status = MAP_ADC14_getEnabledInterruptStatus(); MAP_ADC14_clearInterruptFlag (status); if (status & ADC_INT0) { adcResult = MAP_ADC14_getResult (ADC_MEM0); adcPWMPeriod = (uint_fast16_t)((float)adcResult * TA0_PWMPERIOD / 16383); adcPWMPeriod += 5; MAP_Timer_A_setCompareValue (TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, adcPWMPeriod); //v > 123 ? 128 : v); } } /* * Port 1 interrupt handler. This handler is called whenever switches attached * to P1.1 (S1) and P1.4 (S2) are pressed. */ void PORT1_IRQHandler(void) { uint32_t status = MAP_GPIO_getEnabledInterruptStatus (GPIO_PORT_P1); MAP_GPIO_clearInterruptFlag (GPIO_PORT_P1, status); /* Handles S1 button press */ if (status & GPIO_PIN1) { #ifdef STOPTIMER /* start TimerA0 */ MAP_Timer_A_startCounter (TIMER_A0_BASE, TIMER_A_UP_MODE); #else /* set TimerA1 CCR1 value (reset to last adc value) */ MAP_Timer_A_setCompareValue (TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, adcPWMPeriod); MAP_Interrupt_enableInterrupt (INT_ADC14); #endif /* user P1.0 to see if the interrupt is fired */ MAP_GPIO_setOutputLowOnPin (GPIO_PORT_P1, GPIO_PIN0); } /* Handles S2 button press */ if (status & GPIO_PIN4) { #ifdef STOPTIMER /* stop TimerA0 */ MAP_Timer_A_stopTimer (TIMER_A0_BASE); #else /* set TimerA1 CCR1 value (1 greater that CCR0 - PWM off) */ MAP_Timer_A_setCompareValue (TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, TA0_PWMPERIOD + 1); MAP_Interrupt_disableInterrupt (INT_ADC14); #endif /* user P1.0 to see if the interrupt is fired */ MAP_GPIO_setOutputHighOnPin (GPIO_PORT_P1, GPIO_PIN0); } }
Why does having INT_ADC14 enabled seem to disable all other interrupts in this example?