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.

TMS320F28379D: ADC Results clipping at specific integer value + ADC signal bleed

Part Number: TMS320F28379D

Greetings,

I'm using the F28379D Launchpad to do some testing right now. I've initialized ADC A and ADC C to 16-bit differential modes. According to the launchpad data sheet, all ADCs are referenced at 3V and GND. I have also verified these voltages with a probe.

The ADCs have all been initialized the same way, but with different ePWM triggers. Each ADC fills up it's own DMA buffer. ADC A has two active channels that alternate their SOCs.

The input data is a sine wave at varying low frequencies (100 - 1000Hz), with a Vpp of 3V. No DC bias.

I have two questions:

1) My ADC Results for two channels are clipping/saturating at certain integer values, why is that?

My current guess right now is that the signal I'm feeding the ADCs is not in compliance with the calibration/OTP settings on the device.

The following plots were generated by filling an array with ADC data and then saving that memory region to a text file, and then plotting with Python. (There also appears to be a consistent discontinuity in the sine wave, but I don't know what would be causing it.)

ADC Channels 0/1:

ADC A Channels 4/5:

ADC C Channels 2/3:

2) Signal going into ADC channels is bleeding/leaking over to other ADC channels/ADCs, how do I mitigate this effect?

I think this is a trade-off of chip ADCs with minimal isolation, but the signal leakage is surprisingly large.

Thank You

  • Hi Matt,

    Do you have a scope picture of signals going into ADC A 0/1 4/5 and ADC C 2/3?  Even/odd channel signal amplitudes should be equal but one would seem like it is 180deg out of phase and since VREF is at 3.0V, common mode voltage should be 1.5V.  In your scope shot, the even/odd signals should transect exactly at the 1.5V point to satisfy the differential input requirement.

    Not sure how you determined channel crosstalk - could you share more details on this please?  Could you also share how conversion sequence is on your code?  (e.g. - convert ADCA 0/1 then ADCA4/5, ADC C converts independently ....etc... or the ePWM setup will do).

    Thanks,

    Joseph

  • Joseph,

    I changed my differential signal going into the ADCs to be biased around 1.5V and that fixed the clipping issue as far as I can see. Thank you.

    Crosstalk was inferred from the rest of my software routine. Each ADC fills a DMA buffer, which in turn fills a buffer allocated in the GSRAM. Each buffer than goes through a FFT/phase analysis function that spits out a frequency. What I noticed in the emulation/watch window is that channels that are not receiving a signal will return a correct frequency value when they should just be 0.

    The cross talk isn't completely consistent. A01 affects both A45 and C23, A45 only affects A01, and C23 does not affect either. If I feed ADC A 01 a signal, this is what shows up in the ADC C buffer. However, the reverse is not true if I feed a signal to ADC C 23, where ADC A functions normally.

    Each ADC result register is connected to a DMA Buffer using the built in DMACHXAddrConfig() function.

    Part of the issue I think may be my ePWM setup. ePWM1 (ADC A 01) and ePWM2 (ADC A 45) are intended to be setup to be 180 out of phase so that the SOCs alternate. Here is the initialization code:

    Source:

    Header:

    After reviewing it I think my values for  the CMP and TBPRD registers are wrong. Do you have a suggestion for making these SOCs alternate/be out of phase? I've reviewed all the ePWM modules I thought were relevant, but I haven't been able to decide on a method.

  • Matt,

    I could be wrong but here are my assumptions after looking at your ePWM setup:

    - Triggers are: ADC A 0/1 - ePWM1 SOCA; ADC A 4/5 - ePWM2 SOCA; ADC C 2/3 - ePWM3 SOCA.
    - ePWM1 SOCA is generated every 5000 periods, ePWM2 SOCA is generated every 5000/2 periods; ePWM3 SOCA is generated every 5000 periods.

    If my assumptions are correct, it looks like sampling for ADC A 4/5 is 2x that of ADC A 0/1. The first sample done on ADC A 4/5 (after 5000/2 periods) is correct but the next sample (after 5000 periods), it is channel ADC A 0/1 that gets converted. The next conversion (after 7500 periods) converts ADC A 4/5 again....and so on.... This is probably why it would seem like signal in ADC A 0/1 gets coupled with signal in ADC A 4/5.

    What I recommend is to use both SOCA and SOCB triggers in the ePWM. It is probably a more efficient way of triggering 2 SOCs that are alternating. You need to enable both SOCAEN and SOCBEN. Configure SOCASEL to 0x4 (enable event time-base counter equal to CMPA) and SOCBSEL to 0x6 (enable event time base counter equal to CMPB). You can then assign CMPA and CMPB values accordingly and independently from each other (e.g. assign one every 5000 periods as what you currently have and the other at half of that duration). This way, triggers will not overlap. Lastly, you need to configure the ADC triggers to SOCA (0x5 if using ePWM1) and SOCB (0x6 if using ePWM1) in your ADCSOCxCTL trigger setup for this to work.

    Hope this helps.

    Regards,
    Joseph
  • Joseph,

    Thanks for your help so far I think I understand the ePWM event system a bit better.

    So far I've been able to eliminate any cross-talk between ADC A and ADC C, but I still can't get ADC A01 and ADC A45 to not interfere with each other.

    I've changed my code to the following:

    ADC Source:

    ePWM Source:

    TBPRD is 5000 periods, CMPA is 2500, and CMPB is 5000. I've set the ADC A SOC0 to convert on ePWM1 SOCA, and ADC A SOC4 to convert on ePWM1 SOCB. When I feed a signal to only A01 and look at the incoming data, it looks pretty clear on both buffers so I feel like this is definitely an ePWM problem as you suggested.

    Is there any part of the code that strikes you as incorrect?

    Best,

    Matt

  • Matt,

    The sequence of conversion for the SOCs are SOC0, SOC1,...SOC15 if you did not override the round robin sequence with SOC priority (and I do not see this in your code). What is happening with your current ADC setup is that ADC A SOC0 (configured for channel 0) will convert first, then SOC1, SOC2, SOC3 before converting SOC4 (configured for channel 4). By default, since there is no assignment to ADCSOC1,2 and 3, the channel will be 0 so this would make you think that for some of the conversions on channel 4, you are seeing data from channel 0.

    I think what confused you is SOC# to channel# assignment. Note that this is not exclusive. You can assign any channel to any SOC. This is what makes the ADC of the TMS320F28379D flexible. To fix the issue, use ADCSOC0 (map to channel 0) and ADCSOC1 (map to channel 4) on ADC A and also use ADCSOC0 (map to channel 2) on ADC C to get your conversion sequencing right. You also need to reconfigure INTxSEL accordingly to match your new SOC assignments for the interrupt sources.

    Best regards,
    Joseph
  • Joseph,

    Thank you for the explanations and register suggestions. I reformatted my code and all the modules are operating as expected.

    So I ended up trying two different input signals at the same time and my code is working as intended. I still get the results bleeding over if there is just a single input running, and from some testing (admittedly not very thorough testing) my guess right now is that the unconnected headers/traces on the launchpad are picking up the signal from my signal generator and if one channel pair is left floating then the channels cross talk before it gets to the ADC.

    Best,

    Matt