TMS320F280049C: ADC SOC sequence issue

Part Number: TMS320F280049C

Hi 

I have encountered an ADC SOC sequence issue.

Below is my ADC configuration
                          (1) ADC-A SOC0,SOC1,SOC2,SOC3,SOC5,SOC6,SOC7 conversion share the same trigger source(time-base counter equal to CMPA when the timer is incrementing(Event1).
                          (2) ADC-A SOC4 conversion trigger source is time-base counter equal to CMPA when the timer is decrementing(Event2)
                          (3) CMPA value = 50% period value
                          (4) Timer base mode is up and down
                          (5) All SOC conversion triggered every two PWM cycles
                          (6) ALL SOC ACQPS configuration is the same
                          (7) Do not set any High priority

As I thought Event1 occurred first then Event2 occurred second and the SOC conversion sequence should be SOC0,SOC1,SOC2,SOC3,SOC5,SOC6,SOC7, But actually I Saw the sequence is SOC5,SOC6,SOC7,SOC0,SOC1,SOC2,SOC3, So I can't figurate out why this? Can you give some guidance about it?

I  put a diagram about the ADC configuration ADC_Configuration.pngfor your reference.

  • Hi xu,

    Can you provide more details on timing? How fast is SYSCLK, what speed is ADC configured to and what is the ACQPS setting?  For PWM, what is TBPRD setup to and what is CMPA value and what is PWM speed?  For PWM, up/down counting is selected, correct?  Let's have these values and see what could be happening with the SOC order.

    Regards,

    Joseph

  • Hi Joseph,

    (1)SYSCLK = 100MHz,ADC Clock = 50MHZ, all channels ACQPS= 30
    (2)TBPRD = 500, CMPA = 250, PWM Frequency = 100KHZ, checked PWM UP/Down set correctly

    Regards,

    lucas

  • Hi Lucas,

    Thank you for the additional information as this is needed for the timing analysis.  Based on your configuration the behavior you are seeing is expected. The cause is the round-robin pointer (RRPOINTER) retaining its position from the previous conversion cycle - it is not a bug.

    The C28x ADC round-robin arbiter does NOT reset its pointer when a new trigger fires. It resumes scanning from RRPOINTER + 1, wherever the last conversion left it.

    In your setup, SOC4 is always the last SOC to complete in each cycle because Event2 (CTR=CMPA, DOWN) fires after Event1 and SOC4 queues behind the remaining Event1 SOCs. This leaves RRPOINTER = SOC4 at the end of every cycle.

    When Event1 fires in the next cycle and triggers SOC0,1,2,3,5,6,7 simultaneously, the arbiter scans from RRPOINTER+1 = SOC5. SOC4 is not pending so it is skipped, SOC5 is found first, and the sequence becomes:

    SOC5 -> SOC6 -> SOC7 -> SOC0 -> SOC1 -> SOC2 -> SOC3 (wraps at SOC7)

    This matches exactly what you are observing.

    Here is the timing walkthrough based on the SYSCLK, ADCLK, ACQPS you have provided:

         - ADC conversion time per SOC = (31 + 14) x 20ns = ~900ns

    With TBPRD=500, CMPA=250, up-down mode, PWM=100kHz:
         - Event1 (CTR=CMPA, UP) fires at t = 2.5us into the PWM period
         - Event2 (CTR=CMPA, DOWN) fires at t = 7.5us into the PWM period
         - Gap between Event1 and Event2 = 5.0us

    In steady state (RRPOINTER=SOC4 going in to Event1):

         t=2.5us Event1 fires -> SOC0,1,2,3,5,6,7 all pending
                      RRPOINTER=SOC4, arbiter scans from SOC5

         SOC5 converts (2.5 -> 3.4us)
         SOC6 converts (3.4 -> 4.3us)
         SOC7 converts (4.3 -> 5.2us) [wraps back to SOC0]
         SOC0 converts (5.2 -> 6.1us)
         SOC1 converts (6.1 -> 7.0us)

         t=7.5us Event2 fires -> SOC4 pending
                      SOC2 is actively converting at this moment

         SOC2 converts (7.0 -> 7.9us)
         SOC3 converts (7.9 -> 8.8us) RRPOINTER=SOC3, scan -> SOC4
         SOC4 converts (8.8 -> 9.7us) RRPOINTER=SOC4 [same end state]

    Full cycle order: SOC5, SOC6, SOC7, SOC0, SOC1, SOC2, SOC3, SOC4
    RRPOINTER at end: SOC4 <- locks in, repeats every cycle

    Your results are still valid.  The results registers re SOC-indexed,  not conversion-order-indexed. Regardless of which SOC converts first, SOC0 result always lands in ADCRESULTA0, SOC1 in ADCRESULTA1, and so on. If you are reading each channel from its dedicated result register the data is correct.

    The ordering only matters if you need to know which channel was sampled earliest in time (e.g., phase-sensitive or tightly synchronized sampling).

    You have three options for this:

    Option 1 - Accept the behavior:  Read results from the correct ADCRESULT registers. No code change needed. Recommended if sample time ordering is not critical to your application.

    Option 2 - Use high-priority SOCs (ADCPRICTL) [Recommended if order matters]:  Set SOCPRIORITY = 4. SOC0-SOC3 become high priority and always convert before the round-robin SOCs (SOC5-SOC7), regardless of RRPOINTER state.

         AdcaRegs.ADCPRICTL.bit.SOCPRIORITY = 4; // SOC0-3 high priority

    This guarantees SOC0->SOC1->SOC2->SOC3 always run first after Event1, then SOC5->SOC6->SOC7 follow in round-robin order.

    Option 3 - Renumber the Event2 SOC above SOC7: Reassign the SOC4 channel to SOC8 or higher. RRPOINTER after SOC8 wraps back past SOC0, so Event1 arbitration starts at SOC0 naturally.  No ADCPRICTL change needed.

    Let me know if you have further questions.

    Regards,

    Joseph

  • Hi Joseph,

    Thanks for your detailed analysis and suggestions , I think it can sesolve my issue. Thanks!

    Best&regardsa

    lucas