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.

TMS320F280049C: ADC A half the amplitude of ADC B

Part Number: TMS320F280049C
Other Parts Discussed in Thread: LAUNCHXL-F280049C

Hi there,

I'm having trouble with initializing the ADCs. I do the exact same thing for ADC A and ADC B and if I apply a signal all the ADCs seam to properly sample the signal except of the ADC A returns the signal with half the amplitude compared to ADC B.

Here's my init code:

    // allow adjusting registers
    EALLOW;
    // Enable internal 3.3V reference voltage
    // Enable internal reference on ADCs
    AnalogSubsysRegs.ANAREFCTL.bit.ANAREFASEL = ADC_INTERNAL;
    AnalogSubsysRegs.ANAREFCTL.bit.ANAREFA2P5SEL = ADC_VREF3P3;
    AnalogSubsysRegs.ANAREFCTL.bit.ANAREFBSEL = ADC_INTERNAL;
    AnalogSubsysRegs.ANAREFCTL.bit.ANAREFB2P5SEL = ADC_VREF3P3;

    // configure ADCCLK prescale. Max according to ds is 50MHz.
    AdcaRegs.ADCCTL2.bit.PRESCALE = 2;
    AdcbRegs.ADCCTL2.bit.PRESCALE = 2;

    // Cause the interrupt to be triggered after conversion
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;
    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;
    AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;
    AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;
    AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;
    AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;
    AdcaRegs.ADCSOC6CTL.bit.CHSEL = 6;
    AdcaRegs.ADCSOC7CTL.bit.CHSEL = 7;
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;
    AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1;
    AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2;
    AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;
    AdcbRegs.ADCSOC4CTL.bit.CHSEL = 4;
    AdcbRegs.ADCSOC5CTL.bit.CHSEL = 5;
    AdcbRegs.ADCSOC6CTL.bit.CHSEL = 6;
    AdcbRegs.ADCSOC7CTL.bit.CHSEL = 7;
    // Setup acquisition windows for ADC A and B and all required SOCs
    // (register holds value - 1)
    uint16_t u16Acqps = 24;
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = u16Acqps -1;
    AdcaRegs.ADCSOC1CTL.bit.ACQPS = u16Acqps -1;
    AdcaRegs.ADCSOC2CTL.bit.ACQPS = u16Acqps -1;
    AdcaRegs.ADCSOC3CTL.bit.ACQPS = u16Acqps -1;
    AdcaRegs.ADCSOC4CTL.bit.ACQPS = u16Acqps -1;
    AdcaRegs.ADCSOC5CTL.bit.ACQPS = u16Acqps -1;
    AdcaRegs.ADCSOC6CTL.bit.ACQPS = u16Acqps -1;
    AdcaRegs.ADCSOC7CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC1CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC2CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC3CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC4CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC5CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC6CTL.bit.ACQPS = u16Acqps -1;
    AdcbRegs.ADCSOC7CTL.bit.ACQPS = u16Acqps -1;

    // set all SOCs  to trigger on ePWM1 SOCA. Since no further
    // priorization is taking place the SOCs will be triggered in a
    // round robbing manner
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;
    AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 5;
    AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 5;
    AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 5;
    AdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 5;
    AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 5;
    AdcaRegs.ADCSOC6CTL.bit.TRIGSEL = 5;
    AdcaRegs.ADCSOC7CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC3CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC4CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC5CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC6CTL.bit.TRIGSEL = 5;
    AdcbRegs.ADCSOC7CTL.bit.TRIGSEL = 5;

    // Cause interrupt once SOC7 of ADC A is done
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 7;
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // Enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Make sure INT1 flag is cleared
    AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 7;
    AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; // Enable INT1 flag
    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Make sure INT1 flag is cleared

    // Function for ADC-A interrupt 1. Since ADC-B is setup
    // identically to ADCA it should be done at the same time.
    PieVectTable.ADCA1_INT = &etgadc_A1ISR;

    // Power up the ADC
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    // stop to allow register changes
    EDIS;

And the graph of the results:

Above: ADC_A

Above: ADC_B

Am I missing some setting that remains on default and  therefore causes the issue? Any help would be highly appreciated.

Thanks!

  • Hi Lennart,

    The ADC channel assignment per SOC looks a bit odd to me.  For example, ADCA SOC0-SOC7 channels are assigned to A0-A7 and ADCA SOC0-SOC7 are assigned to B0-B7 in succession.  I'm not sure that this really your intention.  You should assign the SOC channels to the physical channel where the analog signal is fed to the device.  It looks like you wanted to use 8 SOCs (0-7) for both ADCA and ADCB, but you probably are not connecting the sine wave signal to A0-A7 and B0-B7.  Your code expects that you would connect all 8 SOCs to ADC ch 0 to ch 7 which is not possible as some channels are not bonded out.  For instance A7 and B7 channels are not available on any F280049C package configuration.

    Maybe your intention is to feed the signal to one ADCA input and one ADCB input (example, A0 and B1).  In this case the SOC channel assignment for ADCA would be:

         AdcaRegs.ADCSOC[0-7]CTL.bit.CHSEL = 0; [0-7] is just a notation I used here to indicate that you have to use this setup for all the SOCs you are using

    ADCB would also follow the same:

         AdcbRegs.ADCSOC[0-7]CTL.bit.CHSEL = 1;

    Regards,

    Joseph

  • Hi Joseph,

    that's interesting. I actually didn't took a close look whether they are bonded out. I just assumend if A6 and A8 are bounded out. A7 will be bounded out as well.
    I'm just starting with the launchpad dev board and sort of wrote down the config we need at the end.
    My intention was to sample the signal from 16 pins with 2 samples per time instance. Furthermore I aim for basically two burst sampling cycles (without using the burst mode as I figured this is a little more readable and easier to understand for someone who didn't took a closer look in the TRM). So the ePWM SOCA will trigger SOC0-7 for ADC A and ADC B starting with SOC0 and successively going through all SOCs (round robbin) untill SOC7 finally causes the interrupt.

    Even though some pins aren't connected the images are derived from two channels that defintelly ARE connected namingly A1 (sampled from ADC A) and B1 (sampled with ADC B). I also fixed the unbonded pins to ones that are there but the issue persists. Any other suggestions what could cause this? Or is my approach just wrong to begin with?

    Thanks for your help!

  • Hi Lennart,

    To debug the amplitude issue, I suggest using one channel at a time for all the SOCs first.  Maybe there is one ADC channel that is currently connected to or muxed to a different function that is loading the input signal.

    Best regards,

    Joseph

  • Hi Joseph,

    it's beginning to get really strange. I trimmed the design down to a single channel, single ADC design. In this setup the amplitude in ADC A channel 0 (A0 pin) is the same as if I configure it to use ADC B channel 0 (B0 pin). With that I went back in my repo and suddenly all amplitudes where half of the amplitudes showed in the intial question. I then did a rebuild of the project and out of a sudden all channels had the same amplitude.

    Another attempt I did was to replace ADC A with ADC C and ofcourse using other pins for the analog signal. And again ADC B returned the expected amplitude of around 1200. Same on ADC C. So far all this doesn't make any sense and I will try to get some more reliable and reproducable info tomorrow.

  • Hi Lennart,

    Yeah, it is always tricky debugging at first but once the issue is identified, rest should be straightforward.  I'm looking at the LAUNCHXL-F280049C launchpad and I do not see any extra routings on A0 and B0.  Let us check on a few items on your setup:

    1.) LP does not have an external VREF source, which should be the case since your test configured internal VREF 3.3V.  Just double check that there are no other connections on J15 header.  To confirm that device has the correct VREF, measure the voltage across J15 (you will only observe VREF once ADCPWDNZ bit in ADCCTL1 register is set).  Internal VREF 3.3V should produce 1.65V across J15 (internal 2.5V VREF will produce 2.5V.  Internal 3.3V VREF mode has a special circuit that divides the input signal by two before being fed to the SAR input)

     2.) A0 and B0 inputs do not have anything connected at the moment that may cause loading which may lead to amplitude drop, but it is a good practice to add an input capacitor to pre charge the ADC input.  There is a chapter in the ADC TRM section that gives a guidance on how the source/input impedance will affect SH (acqps), but for now try adding an input cap on A0 pin that is around 100pF just for debug purposes.  We can fine tune the value later.  Would you also indicate the value of u16Acqps that you have set?

    3.) Check impedance setting of the sine source.  I'm assuming this is from a waveform generator.  More often, if the impedance setting is not correct, the output of the generator will not be correct.  If you have an oscilloscope the capture the sine source, it would be a good idea to validate the amplitude of the signal as well.  Please also indicate the frequency of the sine signal.

     If you have additional findings, let me know when you get a chance and hopefully the above pointers will facilitate your debug.

    Best regards,

    Joseph

  • Hi Joseph,

    so far nothing new. Just keep seeing crazy behaviour.

    1) Checked Vref. No nothing is connected to J15 and yes I can measure the expected 1.65V. I extended this a little and checked it when I only use ADC B with a single pin. Suddenly VREF turned to 0V and the samples where all 4095 which makes sense if Vref is 0. But why is it 0V?  If I additionally configure vref for ADC A and power it up I get the 1.65V on the VREFHI pin but the signal on ADC B again has twice the amplitude as I would expect.

    2) I don't think capacitors on the input would help. However I will try that once I have access to such capacitors again which will be around 12th april ... (insert Corona excuse). The reason why I don't think this will help is the fact that I use a single output of my signal generator (50Ohm output) and from that I go to all the ADC pins (I know HF guys would like to kill me for that but I'm far far away from HF ;-) ). So if the HW side would cause trouble I'd assume to see the same issue on ALL ADCs and channels. Instead I see differences between ADC A and B (I also tried ADC C which for now behafes the same as ADC B) so I think the issue isn't something like capacitance issues, impedance matching etc but rather some register problem. I feel like I'm missing some register setting.
    The aquisition window is set to 24 sysclk cycles. SYSCLK is 100MHz and ADCCLK is 50MHz.

    3) Regarding impedance, see the above. I don't have access to an oscilloscope right now but as I described above I cannot imagine that the two ADC's are seeing different amplitude signals due to the setup I use. The frequency of my signal is 16.2kHz which I can also approove from what the TMS sampled.

    One other thing I noted is that if I only connect a single pin to the signal source the unconnected pins of ADC A are floating around 130 the unconnected pins on ADC B instead are constantly 0 except of the channel above the channel that the signal is connected to which shows the expected signal with an amplitude of 1/2 of the expected.
    So for example I connect the signal to ADC B B1
    B0 all zero
    B1 shows signal with amplitude of ca 2400
    B2 show signal with amplitude of ca 700 - 800 waveform looks like it's clipping a little on the negative part of the sine wave so like the DC offset wouldn't be large enough.
    B3 small peaks up to value of 60 with the expected frequency

    If I connect the signal to B2:
    B0 all zero
    B1 all zero
    B2 as B1 above
    B3 as B2 above
    B4 as B3 above

    does that make any sense to you? Looks like crosstalk but in a defined direction?

    And I finally have the feeling that I found the issue. I only set Vref for ADC A and ADC B but not for ADC C. If I configure Vref for all three ADCs it seams to work as expected. However, after all that I've seen so far I don't believe anything anymore. I'll come back in the evening and check whether I'm seeing ghosts or a fix.

  • Hi Lennart,

    Thanks for sending the details.  I see no issues with ACQPS, input signal frequency, SYSCLK and ADCCLK.  Not sure yet what to make of the observation you made above when you applied the signal on one pin and measured different values on the other inputs.  My guess is these are probably remaining charge from the sampling cap inside the SAR.  We can look into that later but for now let us focus on why you are seeing have the amplitude on ADCA and you are seeing the expected amplitude on ADCB.

    The part in your launchpad is a 100PZ device.  This has 2 external VREF pins, VREFHIA and VREFHIC (as well as VREFLOA and VREFLOC).  In internal VREF mode, ADC A has its own reference while ADC B shares the reference with ADC C.  In Launchpad, both ADC reference pins are shorted so reference modes should be selected for all 3 ADCs should be the same to prevent the other ADC references from loading each other.  There is also a register that manages the internal connections of the ADC internal references depending on the package type.  This is programmed at the factory but wanted to check the value of this register for the part in your LP.  Can you check the ANAREFPP value for me (AnalogSubsysRegs.ANAREFPP.all)?  This is kind of tricky for the LP since the tow reference pins are shorted at the board :(.

    Forget getting a cap for now but instead, can you make your SOC channel assignments point to ADC A4 and B8?  Just realized there are pre populated caps on some of the channels (sorry, i shut down the Corona excuse :)).  ADC A4 is hardwired to B8 internally so applying the sine signal on A4 will provide signals for both ADC A and B.  Do this with the current ADC internal reference configuration you have in your code and see if you get the same results for both ADCs.  Next, change your configuration to external reference mode but you have to connect J15 to the 3.3V signal or jumper from the on-board 3V3 to the VREFHI side of J15 and connect the VREFLO side to GND.  See if you also get the same results on both ADCs.

    Thanks and regards,

    Joseph

  • Hi Joseph,

    thanks a lot for taking the time to actually read through all my Gyro Gearloose desperatly lost engineer stuff ;-)

    1) I'll check on the crosstalk or remaining charge stuff in two weeks when I have some more independet signal sources at hand. For now, as you said, let's ignore it

    2) The ANAREFPP already made me curious. It is set to disable the reference circuitry for ADC C and enables it for ADC B. Since they are tied together externaly I also set ADC A to produce the ref and than configured ADC B to use the external ref. However this ended up with the same result of ADC B sampling with twice the expected amplitude ... which probably even makes sense as it then has a ref of 1.65 but expecting a ref of 3.3V?

    3) Yeah grate. Now not even Corona is a valid excuse anymore Stuck out tongue
    I first started off removing the Vref config for ADC C as this really seams to fix the issue. I then just connected my source to A4 and checked the result and as expected I see twice the amplitude on ADC B compared to ADC A.
    I then set the Vref to external for both ADCs and connected VrefHi to 3.3V and et voila, both channels show the same amplitude. Awesome! This even makes me feel I understood the problem.

    So if I could ask for one more thing: Address this issue in all the C2000 Ware examples and not just in the adc_ex1_soc_software example (which is where I got the idea from to configure all ADCs Vref). Some examples as i.e. adc_ex11_multiple_soc_epwm just configure ADC A and C to use internal Vref and have the above describe issue.

    Thank you so much Joseph! I really appreciate you're taking the time.
    Have a nice holiday!

    Lennart