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: msp432p4

Part Number: MSP432P401R

hi,

I am using msp432p401r controller .I want to read  multiple adc channels using timer (timera) as trigger source. I am referring adc14_single_conversion_repeat_timera_source code.

and convert it into for  multiple channels. Timer is trigger at 0.5 sec so I toggle the LED in interrupt. My adc ISR is not running at 0.5 sec. Please refer below code.

/* --COPYRIGHT--,BSD
* Copyright (c) 2017, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --/COPYRIGHT--*/
/*******************************************************************************
* MSP432 ADC14 - Single Channel Continuous Sample w/ Timer_A Trigger
*
* Description: In this ADC14 code example, a single input channel is sampled
* using the standard 3.3v reference. The source of the sample trigger for this
* example is Timer_A CCR1. The ADC is setup to continuously sample/convert
* from A0 when the trigger starts and store the results in resultsBuffer (it
* is setup to be a circular buffer where resPos overflows to 0). Timer_A is
* setup in Up mode and a Compare value of 16384 is set as the compare trigger
* and reset trigger. Once the Timer_A is started, after 0.5s it will trigger
* the ADC14 to start conversions. Essentially this example will use
* the Timer_A module to trigger an ADC conversion every 0.5 seconds.
*
* MSP432P401
* ------------------
* /|\| |
* | | |
* --|RST P5.5 |<--- A0 (Analog Input)
* | |
* | |
* | |
* | |
* | |
*
******************************************************************************/
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

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

/* Timer_A Continuous Mode Configuration Parameter */
const Timer_A_UpModeConfig upModeConfig =
{
TIMER_A_CLOCKSOURCE_ACLK, // ACLK Clock Source
TIMER_A_CLOCKSOURCE_DIVIDER_1, // ACLK/1 = 32Khz
16384,
TIMER_A_TAIE_INTERRUPT_DISABLE, // Disable Timer ISR
TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, // Disable CCR0
TIMER_A_DO_CLEAR // Clear Counter
};

/* Timer_A Compare Configuration Parameter */
const Timer_A_CompareModeConfig compareConfig =
{
TIMER_A_CAPTURECOMPARE_REGISTER_1, // Use CCR1
TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE, // Disable CCR interrupt
TIMER_A_OUTPUTMODE_SET_RESET, // Toggle output but
16384 // 16000 Period
};

/* Statics */
static volatile uint_fast16_t resultsBuffer0,resultsBuffer1;
static volatile uint8_t resPos;

int main(void)
{
/* Halting WDT */
MAP_WDT_A_holdTimer();
MAP_Interrupt_enableSleepOnIsrExit();
resPos = 0;

/* Setting up clocks
* MCLK = MCLK = 3MHz
* ACLK = REFO = 32Khz */
MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);

/* Initializing ADC (MCLK/1/1) */
MAP_ADC14_enableModule();
MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 7);

// Set P1.0 to output direction
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0 );

/* Configuring GPIOs (5.5 A0) */
/* Configuring GPIOs for Analog In */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5 | GPIO_PIN4 | GPIO_PIN3 | GPIO_PIN2 | GPIO_PIN1
| GPIO_PIN0, GPIO_TERTIARY_MODULE_FUNCTION);

// MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM7, false);
MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM5, true);
MAP_ADC14_configureConversionMemory(ADC_MEM0,
ADC_VREFPOS_INTBUF_VREFNEG_VSS,ADC_INPUT_A0, false);

MAP_ADC14_configureConversionMemory(ADC_MEM1,
ADC_VREFPOS_INTBUF_VREFNEG_VSS,ADC_INPUT_A1, false);

MAP_ADC14_configureConversionMemory(ADC_MEM2,
ADC_VREFPOS_INTBUF_VREFNEG_VSS,ADC_INPUT_A2, false);

MAP_ADC14_configureConversionMemory(ADC_MEM3,
ADC_VREFPOS_INTBUF_VREFNEG_VSS,ADC_INPUT_A3, false);

MAP_ADC14_configureConversionMemory(ADC_MEM4,
ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A4, false);

MAP_ADC14_configureConversionMemory(ADC_MEM5,
ADC_VREFPOS_INTBUF_VREFNEG_VSS,ADC_INPUT_A5, false);

/* Configuring ADC Memory */

/* Configuring Timer_A in continuous mode and sourced from ACLK */
MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upModeConfig);

/* Configuring Timer_A0 in CCR1 to trigger at 16000 (0.5s) */
MAP_Timer_A_initCompare(TIMER_A0_BASE, &compareConfig);

/* Configuring the sample trigger to be sourced from Timer_A0 and setting it
* to automatic iteration after it is triggered*/
MAP_ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false);

/* Setting up the sample timer to automatically step through the sequence
* convert.
*/
// MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);

/*
* Clear IFGs before enabling interrupt
*/
MAP_ADC14_clearInterruptFlag(0xFFFFFFFFFFFFFFFF);

/* Enabling the interrupt when a conversion on channel 1 is complete and
* enabling conversions */
MAP_ADC14_enableInterrupt(ADC_INT5);
MAP_ADC14_enableConversion();

/* Enabling Interrupts */
MAP_Interrupt_enableInterrupt(INT_ADC14);
MAP_Interrupt_enableMaster();

/* Starting the Timer */
MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);

// /* Triggering the start of the sample */
// MAP_ADC14_enableConversion();
// MAP_ADC14_toggleConversionTrigger();

/* Going to sleep */
while (1)
{
MAP_PCM_gotoLPM0();
}
}

int test = 0;
/* This interrupt is fired whenever a conversion is completed and placed in
* ADC_MEM0 */
void ADC14_IRQHandler(void)
{
uint64_t status;
test++;
status = MAP_ADC14_getEnabledInterruptStatus();
MAP_ADC14_clearInterruptFlag(status);

// Toggle P1.0 output
GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0);

if (status & ADC_INT5)
{

// resultsBuffer[resPos++] = MAP_ADC14_getResult(ADC_MEM0);
resultsBuffer0 = MAP_ADC14_getResult(ADC_MEM0);
resultsBuffer1 = MAP_ADC14_getResult(ADC_MEM1);
}

}

  • Both ADC setting and trigger setting looks right. Can you get into the ADC interrupt? 

  • MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM5, true);

    // MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);

    This configures the ADC with CONSEQ=3 (repeatMode=true) and MSC=0 (ADC_MANUAL_ITERATION). With this combination, you get one conversion per trigger, so 6 conversions take 6*0.5sec=3 sec.

    I suspect you were looking for one burst (6 conversions) every 0.5 sec. To do this, try:

    MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM5, false);   // repeatMode=false (CONSEQ=1) to get only one burst per trigger

    MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);  // MSC=1 to get a full burst per trigger

    and, in the ISR, add:

    > MAP_ADC14_disableConversion();  // ENC=0 then

    > MAP_ADC14_enableConversion();  // ENC=1 per TRM Sec 22.2.8.2

  • Hi Eason & Bruce,

    Thank you for reply.

    I suspect you were looking for one burst (6 conversions) every 0.5 sec. To do this, try:

    --- Yes I am looking for one burst every 0.5 sec

    MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM5, false);   // repeatMode=false (CONSEQ=1) to get only one burst per trigger

    --------------- I understood

    MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);  // MSC=1 to get a full burst per trigger

    ------------------ I understood

    and, in the ISR, add:

    > MAP_ADC14_disableConversion();  // ENC=0 then

    > MAP_ADC14_enableConversion();  // ENC=1 per TRM Sec 22.2.8.2

    -------------Not understand

    Please explain in detail

    I suspect you were looking for one burst (6 conversions) every 0.5 sec. To do this, try:

    MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM5, false);   // repeatMode=false (CONSEQ=1) to get only one burst per trigger

    MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);  // MSC=1 to get a full burst per trigger

    and, in the ISR, add:

    > MAP_ADC14_disableConversion();  // ENC=0 then

    > MAP_ADC14_enableConversion();  // ENC=1 per TRM Sec 22.2.8.2

  • >------------Not understand

    >Please explain in detail

    Read TRM (SLAU356I) Sec 22.2.8.2 (last 2 sentences), which explains it better than I.

  • Hello Bruce,

     This resolved my Issue.

    But I have one more query .

    I want to sense A1 - A6,A7,A14,A15,A21,A22,A23.

    when I am enable Interrupt on A15

    MAP_ADC14_enableInterrupt(ADC_INT15);

    ADC ISR is RUN

    but when I enable interrupt for A23 ADC ISR not generated.

  • ADC_INT23 does not apply to A23, rather it applies to ADC_MEM23, which (I expect) you're not using. I'm not quite sure why ADC_INT15 (->ADC_MEM15) worked, since you're only using ADC_MEM0-5, for which you would use ADC_INT5.

    Or have you changed something else? Do you still use:

    MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM5, false);

    ?