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/TMS320F28377D: 28377 adc to dma configure

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

I want to configure ADCIN0~ADCIN3 to sample current, and using DMACH1 to move ADCResult to databuffer. It confused me several days, my question is as below.

1. i read ADCResult in adcISR, but can't get data.

2. dmaISR only entered one time.

Dose anyone have a relative example? 

Thanks a lot.

  • Hi,

    Hope you have referred the examples at \C2000Ware_X_XX_XX_XX\driverlib\f2837xd\examples\cpu1\adc

    or ADC examples at \C2000Ware_X_XX_XX_XX\device_support\f2837xd\examples\cpu1

    Thanks,

    Katta

  • Yes, I have referred the example.

    C:\ti\C2000Ware_2_00_00_02_Software\device_support\f2837xd\examples\cpu1\adc_soc_continuous_dma

    Below is my adTask Code. Please help to check where is the problem.

    If I comment the four red lines code, adcISR only trigger onetime, and I can get ADC value.

    But if I uncomment the four red lines, adcISR can retrigger, the data is zero, and dmaISR only trigger once.

    Uint16 AdcaResults[40];
    #pragma CODE_SECTION(AdcaResults, ".TI.ramfunc");
    void adca1ISR(void)
    {
    AdcaResults[0] = AdcaResultRegs.ADCRESULT0;
    AdcaResults[1] = AdcaResultRegs.ADCRESULT1;
    AdcaResults[2] = AdcaResultRegs.ADCRESULT2;
    AdcaResults[3] = AdcaResultRegs.ADCRESULT3;
    AdcaResults[4] = AdcaResultRegs.ADCRESULT4;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }

    void dma1ISR(void)
    {
    EALLOW;
    // Clear any spurious flags:
    DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags
    DmaRegs.CH1.CONTROL.bit.ERRCLR = 1; // Clear any spurious sync error flags
    DmaRegs.CH1.CONTROL.bit.RUNSTS = 1;
    EDIS;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
    }

    void ConfigureADC(void)
    {
    EALLOW;
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; //set adc interrupt after transfer finish
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    delay(1000);
    EDIS;
    }

    //setup the ADC to continuously convert on one channel
    void SetupADCContinuous(void)
    {
    Uint16 acqps;

    //determine minimum acquisition window (in SYSCLKS) based on resolution
    if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){
    acqps = 14; //75ns
    }
    else { //resolution is 16-bit
    acqps = 63; //320ns
    }

    EALLOW;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC will convert on channel
    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC will convert on channel
    AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC will convert on channel
    AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC will convert on channel
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles
    AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles
    AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles
    AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles
    AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1; //ADCINT1 pulses are generated whenever an EOC pulse is generated irrespective of whether the flag bit is cleared or not
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 3; //end of SOC3 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //Enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Make sure INT1 flag is cleared
    AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 1;
    AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 1;
    AdcaRegs.ADCINTSOCSEL1.bit.SOC2 = 1;
    AdcaRegs.ADCINTSOCSEL1.bit.SOC3 = 1;
    EDIS;
    }

    void adcTaskInit(void)
    {
    Hwi_Params hwiParams;
    Hwi_Handle dma1Hwi;
    Error_Block eb;

    Error_init(&eb);
    Hwi_Params_init(&hwiParams);

    Hwi_Handle adcaHwi;
    adcaHwi = Hwi_create(32, adca1ISR, &hwiParams, &eb);
    if(adcaHwi == NULL)
    System_abort("Hwi create failed");
    dma1Hwi = Hwi_create(80, dma1ISR, &hwiParams, &eb);
    if(dma1Hwi == NULL)
    System_abort("Hwi create failed");

    //Configure the ADC and power it up
    ConfigureADC();

    //Setup the ADC for continuous conversions on channel 0
    SetupADCContinuous();

    //Initialize results buffer
    memset(AdcaResults,0,40);
    Hwi_enableInterrupt(32);
    Hwi_enableInterrupt(80);
    }

    void DMAInit(void)
    {
    DMAInitialize();
    DMACH1AddrConfig(AdcaResults, &AdcaResultRegs.ADCRESULT0);
    DMACH1BurstConfig(3, 1, 1);
    DMACH1TransferConfig(9, -3, 1);
    DMACH1WrapConfig(100,1,100,1);
    DMACH1ModeConfig(
    DMA_ADCAINT1,
    PERINT_ENABLE,
    ONESHOT_DISABLE,
    CONT_DISABLE,
    //CONT_ENABLE,
    SYNC_DISABLE,
    SYNC_SRC,
    OVRFLOW_DISABLE,
    //THIRTYTWO_BIT,
    SIXTEEN_BIT,
    CHINT_END,
    CHINT_ENABLE
    );
    }

    void adcTaskFxn(void)
    {
    adcTaskInit();
    DMAInit();
    StartDMACH1();
    AdcaRegs.ADCSOCFRC1.all = 0x000F;
    }

  • Is the data zero in the ADCRESULT registers or is it just zero in the DMA destination buffer because the transfer isn't triggering? I'm trying to figure out which part is broken--the ADC conversion or the DMA transfer. Can you clarify? If you comment out all the DMA code, does the ADC work as expected?

    .TI.ramfunc is meant for functions that need to be executed out of RAM, so it's a little odd to put AdcaResults there. I'm not sure this will necessarily be a problem as long as it's in a memory region accessible by the DMA, but it's something to look out for.

    Whitney

  • It seems ADC and DMA both are abnormal.

    First, about ADC. I exclude DMA from my task.

    condition 1. uncomment the four red line, adcaISR entered periodly, I get data to AdcaResults, and the data value is zero. it is abnormal.

    void adca1ISR(void)
    {
    AdcaResults[0] = AdcaResultRegs.ADCRESULT0;
    AdcaResults[1] = AdcaResultRegs.ADCRESULT1;
    AdcaResults[2] = AdcaResultRegs.ADCRESULT2;
    AdcaResults[3] = AdcaResultRegs.ADCRESULT3;
    AdcaResults[4] = AdcaResultRegs.ADCRESULT4;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }.

    condition 2. comment the four red line, adcaISR entered only one time. and the data is correct. It seems the first time ADC conversion is worked.

    Sencondly, about DMA.

    I include DMA into my task, based on the above condition 1, dmaISR only entered one time, why DMA only trigerred once? Pls help to check the DMA configuration.

    Thanks.

  • Condition 2 makes sense. You wouldn't get any further interrupts since you've disabled the ability for the SOCs to be triggered again. I don't see anything in your code that would explain why condition 1 could cause the the data to be zero--all the settings are the same except for the trigger source.

    Does the adc_soc_continuous_dma example work on your hardware?

    Whitney