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.

MSP432 ADC Sampling with Driver Lib

Hi there,


I am trying to make the MSP432 ADC14 sample @ 1 Msps using the Driver Lib. The problem is that the MSP always ends up idling in the faultISR, when I use the function ADC14_getResultArray.

If I don't use this function, my code runs without crashing, but when I inspect the ADC memory registers, they are all zero.


Would be glad if someone could help! This is my code:

#include "msp.h"

#include "pcm.h"
#include "cs.h"
#include "adc14.h"
#include "flash.h"
#include "gpio.h"
#include "interrupt.h"

volatile uint32_t flag;

void adc14_ISR(void) {
	ADC14_clearInterruptFlag(0xFFFFFFFF);
	flag = TRUE;
}

void init_cs(void) {
	// Configuring pins for peripheral/crystal usage and LED for output
	GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
			GPIO_PIN3 | GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);

	// Configure SMCLK output at P7.0
	GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7, GPIO_PIN0,
			GPIO_PRIMARY_MODULE_FUNCTION);

	// Starting HFXT in non-bypass mode without a timeout. Before we start
	// we have to change VCORE to 1 to support the 48MHz frequency
	CS_setExternalClockSourceFrequency(32768, 27120000);
	PCM_setCoreVoltageLevel(PCM_VCORE1);
	FlashCtl_setWaitState(FLASH_BANK0, 2);
	FlashCtl_setWaitState(FLASH_BANK1, 2);
	CS_startHFXT(false);

	// Configure clocks that we need
	CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
	CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_16);
}

void init_adc(void) {
	GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN1,
			GPIO_TERTIARY_MODULE_FUNCTION);

	// Configure ADC
	ADC14_enableModule();
	ADC14_initModule(ADC_CLOCKSOURCE_SMCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 0);
	ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM31, true);
	ADC14_setResolution(ADC_10BIT);

	// Configuring ADC memories
	uint32_t mem;
	for(mem = ADC_MEM0; TRUE; mem <<= 1) {
		ADC14_configureConversionMemory(mem, ADC_VREFPOS_AVCC_VREFNEG_VSS,	ADC_INPUT_A14, false);
		if(mem == ADC_MEM31) break;
	}

	// Configuring timing
	ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
	ADC14_setSampleHoldTime(ADC_PULSE_WIDTH_64, ADC_PULSE_WIDTH_64);

	// Enable interrupt for last ADC memory
	ADC14_enableInterrupt(ADC_INT31);
	ADC14_registerInterrupt(adc14_ISR);
}

void main(void) {
	// Stop watchdog timer
	WDTCTL = WDTPW | WDTHOLD;
	GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
	P1DIR |= BIT0;

	init_cs();
	init_adc();

    __enable_interrupt();

	ADC14_enableConversion();
	ADC14_toggleConversionTrigger();

	flag = FALSE;
	uint16_t res[32];

	while(TRUE) {
		if(flag) {
			ADC14_getResultArray(ADC_MEM0, ADC_MEM31, res);
			flag = FALSE;
		}
	}
}

  • Hello,

    I've been able to duplicate your problem with using the ADC14_getResultArray(); however, since you are configuring ADC to be multiple sequence mode, ADC14_getMultiSequenceResult(res) would be better suited for retrieving the data. 

    //*****************************************************************************
    //
    //!
    //! Returns the conversion results of the currently configured multi-sequence
    //! conversion. If a multi-sequence conversion has not happened, this value
    //! is unreliable. Note that it is up to the user to verify the integrity of
    //! and proper size of the array being passed. If there are 16 multi-sequence
    //! results, and an array with only 4 elements allocated is passed, invalid
    //! memory settings will occur
    //!
    //! \param res conversion result of the last multi-sequence sample
    //! in an array of unsigned 16-bit integers
    //!
    //! \return None
    //!
    //
    //*****************************************************************************
    extern void ADC14_getMultiSequenceResult(uint16_t* res);

    //*****************************************************************************
    //
    //!
    //! Configures the ADC module to use a multiple memory sample scheme. This
    //! means that multiple samples will consecutively take place and be stored in
    //! multiple memory locations. The first sample/conversion will be placed in
    //! memoryStart, while the last sample will be stored in memoryEnd.
    //! Each memory location should be configured individually using the
    //! ADC14_configureConversionMemory function.
    //!
    //! The ADC module can be started in "repeat" mode which will cause the
    //! ADC module to resume sampling once the initial sample/conversion set is
    //! executed.  For multi-sample mode, this means that the sampling of the
    //! entire memory provided.
    //!
    //! \param memoryStart Memory location to store first sample/conversion
    //!         value. Possible values include:
    //!         - \b ADC_MEM0 through \b ADC_MEM31
    //! \param memoryEnd Memory location to store last sample.
    //!     Possible values include:
    //!         - \b ADC_MEM0 through \b ADC_MEM31
    //! \param repeatMode Specifies whether or not to repeat the conversion/sample
    //!         cycle after the first round of sample/conversions. Valid values
    //!         are true or false.
    //!
    //! \return false if setting fails due to an in progress conversion
    //
    //*****************************************************************************
    extern bool ADC14_configureMultiSequenceMode(uint32_t memoryStart,
            uint32_t memoryEnd, bool repeatMode);
    
    //*****************************************************************************

    Sincerely,

    Sean

  • Dear Sean,

    thanks for the clarification and for the tests you made!

    Best, Zaphod

**Attention** This is a public forum