AnsweredAssumed Answered

ADuCM3029: ADC Subsystem - ADC_STAT.DONE bit is never set

Question asked by tdezotti on Jan 29, 2018
Latest reply on Feb 7, 2018 by Narsimh

Hi,

 

I'm having some trouble configuring the ADC subsystem of the ADuCM3029. I'm using the ADICUP3029 board and CrossCore Embedded Studio.

I choose channel 2 for a single conversion.

Although I set ADC_IRQ_EN.CNVDONE to 0x01, I'm waiting ADC_STAT.DONE2 to be set, but this bit is never 1.

What am I doing wrong?

 

===

/*
 * ADuCM3029_Project_Test__ADC_Config.c
 *
 *  Created on: 26 de jan de 2018
 *      Author: tiago.dezotti
 */

 


#include <sys/platform.h>

 

#include "ADuCM3029_Project_Test__ADC_Config.h"
#include "ADuCM3029_Project_Test__TMR_Config.h"

 

 

uint16_t config_ADC(void)
{
    config_samptime(SAMPTIME);

 

    powerup_adc();

 

    program_adc();

 

    return(0x0033);
}

 

uint16_t powerup_adc(void)
{
    enable_powerup_adc();

 

    set_powerup_wait_adc();

 

    set_vref_adc();

 

    set_refbuf_adc();

 

    enable_adc();

 

    config_3_5_ms_timer();

 

    wait_3_5_ms_timer();

 

    clear_ready_adc();

 

    start_cal_adc();

 

    return(0x0033);
}

 

uint16_t program_adc(void)
{
    uint16_t adc2_value = 0x0000;

 

    select_channel_adc(SEL_CHANNEL_ADC);


    enable_int_adc();

 

    start_conv_adc();

 

    wait_conv_done_adc();

 

    adc2_value = read_data_adc();

 

    clear_flag_done_adc();

 

    disable_adc();

 

    return(adc2_value);

 

}

 

uint16_t config_samptime(uint8_t samp_time)
{
    *pREG_ADC0_CNV_TIME |= samp_time;

 

    return(0x0033);
}

 

uint16_t enable_powerup_adc(void)
{
    //Set the ADC_CFG.PWRUP bit (0) to power up the ADC.
    *pREG_ADC0_CFG |= 0x0001;

 

    return(0x0033);
}

 

uint16_t set_powerup_wait_adc(void)
{
    uint32_t clock_div = 0x00000000;

 

    //Set ADC_PWRUP.WAIT bits as 526/(CLKG_CLK_CTL1.PCLKDIVCNT field).

 

    clock_div = *pREG_CLKG0_CLK_CTL1 & 0x00003F00;

 

    clock_div = clock_div >> 8;

 

    *pREG_ADC0_PWRUP = 526/clock_div;

 

    return(0x0033);
}

 

uint16_t set_vref_adc(void)
{
    //Select 1.25 V as reference voltage using the ADC_CFG.VREFSEL bit (1).

 

    *pREG_ADC0_CFG |= 0x0002;

 

    return(0x033);
}

 

uint16_t set_refbuf_adc(void)
{
    //Assert the ADC_CFG.REFBUFEN bit (2).

 

    *pREG_ADC0_CFG |= 0x0004;

 

    *pREG_ADC0_CFG1 |= 0x0001;

 

    return(0x0033);
}

 

uint16_t enable_adc(void)
{
    //Assert the ADC_CFG.EN bit (4).

 

    *pREG_ADC0_CFG |= 0x0010;

 

    return(0x0033);
}


uint16_t clear_ready_adc(void)
{
    //Write 1 to clear the ADC_STAT.RDY bit (15).

 

    *pREG_ADC0_STAT |= 0x8000;

 

    return(0x0033);
}

 

uint16_t start_cal_adc(void)
{
    uint16_t wait_adc_cal = 0x0000;

 

    //Set the ADC_CFG.STARTCAL bit (5) to start the calibration cycle.

 

    *pREG_ADC0_CFG |= 0x0020;

 

    //Wait ADC_STAT.CALDONE bit (14).

 

    wait_adc_cal = *pREG_ADC0_STAT & ADC_CAL_BIT;

 

    while (wait_adc_cal != ADC_CAL_BIT)
    {
        wait_adc_cal = *pREG_ADC0_STAT & ADC_CAL_BIT;
    }

 

    return(0x0033);
}

 

uint16_t select_channel_adc(uint16_t sel_ch)
{
    //Set ADC_CNV_CFG.SEL bits (7-0) and select channel for conversion (for instance, channel 2).

 

    *pREG_ADC0_CNV_CFG |= sel_ch;

 

    return(0x0033);
}

 

uint16_t enable_int_adc(void)
{
    //Set ADC_IRQ_EN.CNVDONE = 0x1 to enable interrupt when conversion is done.

 

    *pREG_ADC0_IRQ_EN |= 0x0001;

 

    return(0x0033);
}

 

uint16_t start_conv_adc(void)
{
    //Set ADC_CNV_CFG.SINGLE bit (14) to start the conversion.

 

    *pREG_ADC0_CNV_CFG |= 0x4000;

 

    return(0x0033);
}

 

uint16_t wait_conv_done_adc(void)
{
    uint16_t wait_adc_ch2_conv_done = 0x0004;

 

    //Wait ADC_STAT.DONE2 bit (2).

 

    wait_adc_ch2_conv_done = *pREG_ADC0_STAT & ADC_CH2_CONV_DONE;  

 

    while (wait_adc_ch2_conv_done != ADC_CH2_CONV_DONE)
    {
        wait_adc_ch2_conv_done = *pREG_ADC0_STAT & ADC_CH2_CONV_DONE;
    }

 

    return(0x0033);
}

 

uint16_t read_data_adc(void)
{
    //Read ADC_CH2_OUT.RESULT to read the conversion result.

 

    return(*pREG_ADC0_CH2_OUT);
}

 

uint16_t clear_flag_done_adc(void)
{
    //Set ADC_STAT[0] to clear the interrupt.

 

    *pREG_ADC0_STAT |= 0x0001;

 

    return(0x0033);
}

 

uint16_t disable_adc(void)
{
    *pREG_ADC0_CNV_CFG &= 0xFFEE;

 

    return(0x0033);
}

 

===

 

===

/*
 * ADuCM3029_Project_Test__ADC_Config.h
 *
 *  Created on: 26 de jan de 2018
 *      Author: tiago.dezotti
 */

 

#ifndef ADUCM3029_PROJECT_TEST__ADC_CONFIG_H_
#define ADUCM3029_PROJECT_TEST__ADC_CONFIG_H_

 

#define SAMPTIME 0x80
#define ADC_RDY_BIT 0x8000
#define ADC_CAL_BIT 0x4000
#define ADC_CH2_CONV_DONE 0x0004
#define SEL_CHANNEL_ADC 0x0004

 

uint16_t config_samptime(uint8_t);
uint16_t enable_powerup_adc(void);
uint16_t set_powerup_wait_adc(void);
uint16_t set_vref_adc(void);
uint16_t set_refbuf_adc(void);
uint16_t enable_adc(void);
uint16_t clear_ready_adc(void);
uint16_t start_cal_adc(void);
uint16_t powerup_adc(void);
uint16_t select_channel_adc(uint16_t);
uint16_t enable_int_adc(void);
uint16_t start_conv_adc(void);
uint16_t wait_conv_done_adc(void);
uint16_t read_data_adc(void);
uint16_t clear_flag_done_adc(void);
uint16_t disable_adc(void);
uint16_t program_adc(void);
uint16_t config_ADC(void);

 

#endif /* ADUCM3029_PROJECT_TEST__ADC_CONFIG_H_ */

===

Outcomes