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.

AM4379: GP EVM ADC1 problem

Part Number: AM4378
Other Parts Discussed in Thread: TMDSEVM437X

Hi all,

I’m testing the operation of the ADC1 in the following environment.

HW : TMDSEVM437X Rev.1.5B

SW : C:\ti\pdk_am437x_1_0_5  &  C:\ti\pdk_am437x_1_0_8

(Problem) 

ADC1 can not measure accurately if a voltage of 1.6 V or less is input.

I checked the register, but I do not know the cause.

By the way, ADC0 is correctly converted.

Input voltage 1.8V -> (conversion value)  4096 = 1.8V

Input voltage 1.6V -> (conversion value) 3640 = 1.6V

Input voltage 1.2V -> (conversion value) 3413 = 1.5V

Input voltage 1.0V -> (conversion value) 2958 = 1.3V

Input voltage 0.4V-> (conversion value) 2048 = 0.9V

Input power supply is regulated DC power supply.

The setting of ADC1 is as follows.

/* ADC1(MagCard) Wake-Up */
regVal = HW_RD_REG32(SOC_CM_PER_REG + PRCM_CM_PER_MAG_CARD_CLKCTRL);
regVal |= PRCM_CM_PER_MAG_CARD_CLKCTRL_MODULEMODE_ENABLE;
HW_WR_REG32((SOC_CM_PER_REG + PRCM_CM_PER_MAG_CARD_CLKCTRL), regVal);
while ((HW_RD_REG32(SOC_CM_PER_REG + PRCM_CM_PER_MAG_CARD_CLKCTRL) & \
PRCM_CM_PER_MAG_CARD_CLKCTRL_MODULEMODE_MASK) != \
PRCM_CM_PER_MAG_CARD_CLKCTRL_MODULEMODE_ENABLE);

/* Configure the clock divider value. (16bit Register) */
HW_WR_REG16((ADC1_BASE_ADDR + ADC1_CLKDIV), ((ADC1_MODULE_CLOCK/ADC1_AFE_CLOCK) - 1));

/* ADC1 Control value */
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_CTRL),(0x63));

/* ADC1 Config & Delay setup */
/* Step1 */
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPCONFIG1),(0x40001));
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPDELAY1),(0));

/* Step2 */
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPCONFIG2),(0x40001));
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPDELAY2),(0));

/* Step3 */
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPCONFIG3),(0x40001));
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPDELAY3),(0));

/* Step4 */
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPCONFIG4),(0x40001));
HW_WR_REG32((ADC1_BASE_ADDR + ADC1_STEPDELAY4),(0));

Best regards,

Sasaki

  • The RTOS team have been notified. They will respond here.
  • Hi,

    To measure the voltage, did you refer to the ti\starterware\examples\adc\volt_measure example? If ADC0 is accurate, do you follow the same code configure the ADC1?

    Regards, Eric
  • Hi Eric-san,

    Thank you for your reply.

    lding said:
    Hi,

    To measure the voltage, did you refer to the ti\starterware\examples\adc\volt_measure example?

    Regards, Eric

    Yes.

    lding said:
    Hi,

    If ADC0 is accurate, do you follow the same code configure the ADC1?

    Regards, Eric

    Because API of ADC1 is not in Starterware, I created a new code.

    The register setting is almost the same.

    I would like to know how to use ADC1 in the same way as ADC0

    Best regards,

    Sasaki

  • Is there any information?
  • Is there information on why ADC1 can not convert low voltage correctly?
  • Hi,

    I looked at your code for ADC1 vs ADCAppInit() in the volt measurement fro ADC0. Your ADC wake-up is equivalent to PRCMModuleEnable(). The Configure the clock divider value. (16bit Register) is equivalent to TSCADCClkDivConfig. Then the rest code differs.

    Since there is no ADC1 code from Sitara, I would think the first trial would be modifying the ADC0 instance in the existing code to ADC1 to see if it works. Have you tried that approach? If you compare the ADC0 and ADC1 registers they would be the same if you only changed the instance.

    Regards, Eric
  • Hi lding-san,

    Thank you for your reply.

    lding said:


    I looked at your code for ADC1 vs ADCAppInit() in the volt measurement fro ADC0. Your ADC wake-up is equivalent to PRCMModuleEnable(). The Configure the clock divider value. (16bit Register) is equivalent to TSCADCClkDivConfig. Then the rest code differs.

    Since there is no ADC1 code from Sitara, I would think the first trial would be modifying the ADC0 instance in the existing code to ADC1 to see if it works. Have you tried that approach? If you compare the ADC0 and ADC1 registers they would be the same if you only changed the instance.

    Just changing the instance did not reflect the register setting correctly to the device.

    So I created the original code and set the register of ADC 1

    so that it has the same setting as ADC 0.

    Attach the file of my survey result.
    The ADC0 and ADC1 register settings are the same, but the conversion result of ADC1 is incorrect.

    Best regards,

    Sasakiadc.xlsx

  • Hi,

    In your code, you enabled STEP_CONFIG for continuous mode and channel select with 0x40001 why the register dump are different (0x04080060)? Did your code enable STEP? why STEPEN is 0?

    Do you have the CCS project for both ADC0 and ADC1 for the test? if you can attach here? Thanks!

    Regards, Eric
  • Hi Eric-san,

    Thank you for your reply.

    lding said:
    Hi,

    In your code, you enabled STEP_CONFIG for continuous mode and channel select with 0x40001 why the register dump are different (0x04080060)? Did your code enable STEP? why STEPEN is 0? 

    Do you have the CCS project for both ADC0 and ADC1 for the test? if you can attach here? Thanks!

    Since I was testing with various register settings, the diagram and the program were different. I will attach the project that I last tested.

    The ADC0 project is the Starterware default project

    adc0.zipadc1.zip

    Best regards,

    Sasaki

  • I want to organize the contents, close this thread and open another thread.
  • Part Number: AM4378

    Hi all,

    I can not understand with the operation of ADC1.

    When I run the program with attached file, the conversion accuracy of ADC1 is bad.

    However, after running this program I made the following operations in CCS,

    the accuracy of ADC1 improved.

    1. Suspend(Alt + F8) with CCS 
    2. Change "ADC1_CLKDIV" from 0x07 to 0x17 in the register window.
    3. Return "ADC1_CLKDIV" from 0x17 to 0x07 in the register window.
    4. Resume(F8) with CCS

    Do you know why this will happen?
    How can I use the ADC 1 accurately without performing the above operations?

    #define CM_PER_BASE_ADDR (0x44df8800)
    #define PRCM_CM_PER_ADC1_CLKCTRL (CM_PER_BASE_ADDR + 0x230)

    #define ADC1_BASE_ADDR (0x4834C000)
    #define ADC1_CLKDIV (ADC1_BASE_ADDR + 0x4C)
    #define ADC1_CTRL (ADC1_BASE_ADDR + 0x40)
    #define ADC1_STEPEN (ADC1_BASE_ADDR + 0x54)
    #define ADC1_STEPCONFIG1 (ADC1_BASE_ADDR + 0x64)
    #define ADC1_STEPDELAY1 (ADC1_BASE_ADDR + 0x68)
    #define ADC1_STEPCONFIG2 (ADC1_BASE_ADDR + 0x6C)
    #define ADC1_STEPDELAY2 (ADC1_BASE_ADDR + 0x70)
    #define ADC1_STEPCONFIG3 (ADC1_BASE_ADDR + 0x74)
    #define ADC1_STEPDELAY3 (ADC1_BASE_ADDR + 0x78)
    #define ADC1_STEPCONFIG4 (ADC1_BASE_ADDR + 0x7C)
    #define ADC1_STEPDELAY4 (ADC1_BASE_ADDR + 0x80)
    #define ADC1_STEPCONFIG16 (ADC1_BASE_ADDR + 0xDC)
    #define ADC1_FIFO0DATA (ADC1_BASE_ADDR + 0x100)

    #define ADC1_AFE_CLOCK 3000000U /* afeInClk */
    #define ADC1_MODULE_CLOCK 24000000U/* modClk */

    /* Macro representing the voltage resolution. */
    #define VOLTAGE_RESOLUTION (439U)

    /**
    * main.c
    */
    int main(void)
    {
    unsigned int data;
    unsigned int reg_d;

    *(volatile unsigned int *)PRCM_CM_PER_ADC1_CLKCTRL = 2; // Module is explicitly enabled
    while(reg_d != 2)
    {
    reg_d = (*(volatile unsigned int *)PRCM_CM_PER_ADC1_CLKCTRL & 2);
    }

    /* Configure the clock divider value. (16bit Register) */
    *(volatile unsigned short *)ADC1_CLKDIV = 0x7;// ((ADC1_MODULE_CLOCK/ADC1_AFE_CLOCK) - 1);
    *(volatile unsigned int *)ADC1_CTRL = 1; // ADC enable
    *(volatile unsigned int *)ADC1_STEPEN = 0;
    *(volatile unsigned int *)ADC1_STEPCONFIG1 = 0x1;
    *(volatile unsigned int *)ADC1_STEPDELAY1 = 0;

    while(1)
    {
    *(volatile unsigned int *)ADC1_STEPEN = 2; // setepconfig 1 start
    data = *(volatile unsigned int *)ADC1_FIFO0DATA;
    data = (data & 0x000FFF);
    data = (data * VOLTAGE_RESOLUTION) / 1000U;
    }

    }

    3240.ADC1.zip

    adc1_result.xlsx

    Best regards,

    Sasaki

  • Threads have been merged. Please do not open multiple threads on the same subject.
  • Hi,

    I looked at your ADC0 code and ADC1 code then the new ADC1 code, there are difference in one shoot or continuous mode with average, GP mode or 4-wire mode, using 1 steps or using 4 steps, and using FIFO0 and FIFO1. I thought you tested a lots of combinations.

    In the final ADC1 code, this is the one shot, GP mode and sampling on the first channel into FIFO0. Is it correct with this code only changing the CLKDIV (0x7--->0x17---->0x7) made the difference?

    The clock divider is the ratio of module clock/afe clock -1. AFE clock is 3 MHz. From TRM Figure 6-21, the ADC0 clock comes only from CLK_M_OSC, which is 24MHz. However, ADC1 clock is selected from CLK_M_OSC (24MHz) or PER_CLKOUTM2 (192MHz).

    By default, this is PER_CLKOUTM2 ( Table 6-182. PRCM_CM_CLKSEL_ADC1_CLK Register Field Descriptions). This is register 0x44df424C. I think if you program this from "1" to "0". Then the ADC1 should work.

    Regards, Eric
  • Hi Eric-san,

    Thank you for your special support.
    I will check it and I will report it when the problem improves.

    Best regards,
    Sasaki
  • Hi Eric-san,

    ADC1 converted correctly!!

    Thank you very much!

    Best regards,

    Sasaki