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.

CCS/MSP432P401R: Initializing an ADC and inputting data to a circular buffer (queue)

Part Number: MSP432P401R

Tool/software: Code Composer Studio

Hi I'm struggling to correctly initialize one of the ADC ports and have it take data and put it into a circular buffer. I have the buffer working when I manually input data but I haven't been able to initialize the ADC correctly or place data into the buffer I created. I'm using the libraries provided by TI for the MSP to try to initialize the ADC with no success so far.

This is my main.c 

// includes
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include "setup.h"
#include <stdint.h>
#include <stdbool.h>
#include <queue.h>
#include <stdio.h>
#include <csvCreate.h>

// variables
static volatile uint16_t curADCResult;
static volatile float normalizedADCRes;
volatile uint32_t j;

// function declaration
void ADC14_IRQHandler();

int main(void)
{

    // Stop watchdog timer
    WDT_A_hold(WDT_A_BASE);
    initLED();
    initEnable14();
    ADC14_enableModule();
    initADC14();
    initEnable14();
    ADC14_IRQHandler();

//    int a[3][3]={{50,50,50},{60,60,60},{70,70,70}};
//
//    char str[100];
//
//    printf("\n Enter the filename :");
//
//    gets(str);
//
//    createCSV(str,a,3,3);

    return 0;
}

//*****************************************************************************
// Interrupt routine handler
//*****************************************************************************
void ADC14_IRQHandler(void)
{
    uint64_t status = ADC14_getInterruptStatus();
    ADC14_clearInterruptFlag(status);
    initDisable14();

    if (ADC_INT14 & status)
    {
        curADCResult = ADC14_getResult(ADC_MEM14);
        normalizedADCRes = (curADCResult * 3.3) / 16384;
        for (j=1; j<=SIZE; j++){
            enQueue(ADC_MEM14);
            display();
        }

    }
    initEnable14();
}

And this is my initialization file

#include "setup.h"
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

//*****************************************************************************
// LED setup
//*****************************************************************************
void initLED(){
    // Set P1.0 to output direction
    // Red P2.0
    // Green P2.1
    // Blue P2.2
    GPIO_setAsOutputPin(GPIO_PORT_P2,
                        GPIO_PIN0
                        | GPIO_PIN1
                        | GPIO_PIN2);
    GPIO_setOutputLowOnPin(GPIO_PORT_P2,
                        GPIO_PIN0
                        | GPIO_PIN1
                        | GPIO_PIN2);
}

void blinkLEDRed(){
    // Toggle P1.0 output
    GPIO_toggleOutputOnPin(
        GPIO_PORT_P2,
        GPIO_PIN0
        );
}

void blinkLEDGreen(){
    // Toggle P1.0 output
    GPIO_toggleOutputOnPin(
        GPIO_PORT_P2,
        GPIO_PIN1
        );
}

void blinkLEDBlue(){
    // Toggle P1.0 output
    GPIO_toggleOutputOnPin(
        GPIO_PORT_P2,
        GPIO_PIN2
        );
}

//*****************************************************************************
// ADC initialization
//*****************************************************************************
void initADC14(){
    ADC14_enableModule();
    // Keep divided by 1 so that it will sample at max speed
    ADC14_initModule(ADC_CLOCKSOURCE_ADCOSC, ADC_PREDIVIDER_1,
             ADC_DIVIDER_1, 0);

    // Configuring GPIOs for Analog In
    // Pin 4.5
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4,
            GPIO_PIN5, GPIO_TERTIARY_MODULE_FUNCTION);

    ADC14_configureMultiSequenceMode(ADC_MEM14,
            ADC_MEM14, true);
    // configure memory and pin locations
    // MEM6 will be used to make a buffer
    // INPUT_A6 will be ADC6 checking for the threshold
    // A6 P4.7
    ADC14_configureConversionMemory(ADC_MEM14,
             ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A14,
             ADC_NONDIFFERENTIAL_INPUTS);

    ADC14_setResolution(ADC_14BIT);
}

void clearFlag(){
    ADC14_clearInterruptFlag(ADC_INT14);
}

//*****************************************************************************
// Interrupt routine initialization
//*****************************************************************************
void initEnable14(){
        // Enable Interrupt
        ADC14_enableInterrupt(ADC_INT14);
        Interrupt_enableMaster();
}

void initDisable14(){
        // Disable Interrupt
        ADC14_disableInterrupt(ADC_INT14);
}

And if it's needed this is the queue I'm using

#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <setup.h>
#include "queue.h"


int items[SIZE], front = -1, rear = -1;
volatile uint32_t i;

////*****************************************************************************
//// Circular buffer
////*****************************************************************************

void enQueue(int value){
if(rear == SIZE-1){
blinkLEDBlue(); // Queue is Full
for(i=20; i>0; i--);
}
else {
if(front == -1)
front = 0;
rear++;
items[rear] = value;
printf("\nInserted -> %d", value);
}
}

void deQueue(){
if(front == -1){
blinkLEDRed(); // Queue is Empty
for(i=20; i>0; i--);
}
else{
printf("\nDeleted : %d", items[front]);
front++;
if(front > rear)
front = rear = -1;
}
}

void display(){
if(rear == -1){
blinkLEDRed(); // Queue is Empty
for(i=20; i>0; i--);
}
else{
int i;
printf("\nQueue elements are:\n");
for(i=front; i<=rear; i++)
printf("%d\t",items[i]);
blinkLEDGreen(); // Queue is Empty
for(i=20; i>0; i--);
}
}

  • I think that you will find these examples helpful in setting up a repeated measurement of a single channel.

    dev.ti.com/.../

    dev.ti.com/.../

    I would encourage you to be mindful of the sampling rate of the adc and how often if writes to the buffer.

    Regards,
    Chris
  • I've been looking at the examples for a reference but they don't store the data into a buffer, and I'm kind of unsure what the examples are doing.

    As for the sampling rate of the adc and how often it writes to the buffer, is there some sort of calculation I can do that will tell me how fast I can sample vs. how fast the buffer can write?

    Thank you,
    Kaitlin
  • In the first example, adc14_single_conversion_repeat. The sampling frequency is defined by how often the instruction MAP_ADC14_toggleConversionTrigger(); is called. It is called initially in main and then in the ISR the API is called again once the data is moved from the result register into the memory variable. In the repeat_timera_source example a timer is configured and used to periodically trigger the ADC conversion. The timer source is ACLK, which is defined as the 32Khz REFO. The period is defined as (16384+1) clocks which results in 0.5seconds, or 2 samples per second. In this second example you see the result stored in the buffer, resultsBuffer[].

    I am not sure I understand what you mean by how fast the buffer can write. Writing to memory (SRAM) is dictated by the CPU frequency. If you need to send data from the buffer to another device via SPI, UART, etc, then there is the associated overhead of the communication.

    Chris

**Attention** This is a public forum