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: TMS320F28379D GPIO and ADC

Part Number: TMS320F28379D
Other Parts Discussed in Thread: TMDSCNCD28379D, TMS320F2812

Hi everybody,

I'm using the TMDSCNCD28379D controlCARD for a new project, but I have two issues.

First one concerned GPIO in input mode :

  • When it's concerning GPIO A or GPIO B, there's no problem (for example, configuring GPIO30 as an input)
GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;   // Enable pullup on GPIO30
GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 0;  // Enable GPIO on GPIO30
GpioCtrlRegs.GPADIR.bit.GPIO30 = 0;   // Configure GPIO30 as intput
  • But when it's concerning GPIO C, I need to disable pullup (for example, configuring GPIO74 as an input)
   GpioCtrlRegs.GPCPUD.bit.GPIO74 = 1;    // Disable pullup on GPIO74
   GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 0;   // GPIO74 = GPIO74
   GpioCtrlRegs.GPCDIR.bit.GPIO74 = 0;    // GPIO74 = input 

Is it an hardware issue?

Second thing is not an issue, but a question :

Before, I used a TMS320F2812 ; to have a continuous ADC conversion, I could proceed like this :

- Start a SEQ1 conversion : 

AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;

- Wait for interrupt on EOS (End of sequence) : 

while (AdcRegs.ADCST.bit.INT_SEQ1 == 0)

- Clear the SEQ1 interrupt flag bit :

AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;

- And conversion start again.

Now, with the 28379D, I want to use a software trigger (INT1). I proceed like this :

ADC Configuration :

    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;          // SOC0 will convert pin A0 on ADC-A
    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;          // SOC1 will convert pin A1 on ADC-A
    AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;          // SOC2 will convert pin A2 on ADC-A
    AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;          // SOC3 will convert pin A3 on ADC-A

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 3;      // End of SOC3 will set INT1 flag on ADC-A

- Start a conversion :

AdcaRegs.ADCSOCFRC1.all = 0x000F;  //     SOC3, SCO2, SOC1 & SOC0     are used on ADC-A - Start of conversion

- Wait for interrupt on EOS (End of sequence) : 

while(AdcaRegs.ADCINTFLG.bit.ADCINT1 == 0);

- Clear the interrupt flag bit :

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;      // Acknowledge INT1 flag on ADC-A

- But conversion doesn't start again, I need to use again the instruction :

AdcaRegs.ADCSOCFRC1.all = 0x000F;  //     SOC3, SOC2, SOC1 & SOC0     are used on ADC-A - Start of conversion

Is it normal? Do I have to start a new conversion each time?

Thanks for your answer.

Regards,

  • Due to US holidays, you can expect a response by 3'rd Dec.

  • Hi Electrocc,

    Can you clarify the specific problem with the input in GPC bank?  Is the same source used to drive the input in both cases?  Is this any input on GPC, or just GPIO74? 

    As far as the ADC, yes, the conversions will not auto-restart.  You can either software force the conversions again, or you can setup ADCINT1 to re-trigger SOC0 through SOC3.  This re-triggering is configured through the ADCINTSOCSEL1 and ADCINTSOCSEL2 registers.     

  • Hi Devin,

    Thanks for your reply.

    I can not do the test today, but as I remember, I've tried also with GPIO 64, GPIO72, and the same issue appears.

    Thank you

    Electrocc

  • And yes, I've used exactly the same source to drive inputs.

    When pull-up is enabled, input is set to 1 and never changed, 0 or 1 on the input.

    When pull-up is disabled, input changed if we modify input level (0 or 1)

  • Hi,

    2 others questions concerning ADC:

    • With the old MCU (F2812), I had to use these lines :
      while (AdcRegs.ADCST.bit.INT_SEQ1 == 0) { } // Wait for interrupt on EOS (End of sequence)
      // Software wait = (HISPCP*2) * (ADCCLKPS*2) * (CPS+1) cycles
      //               = (1*2)      * (3*2)        * (0+1)   = 12 cycles
      asm(" RPT #12 || NOP");

      Is it mandatory?

    • I want to use ADCINT1 to start a new conversion, and not start a new conversion with software each time. But there's something wrong :
      void Init_Adc(void)
      {
      
          EALLOW; /* Enable Write Access to Protected Space */
      
      //--- Reset the ADC.  This is good programming practice.
          DevCfgRegs.SOFTPRES13.bit.ADC_A = 1;    // ADC-A is reset
          DevCfgRegs.SOFTPRES13.bit.ADC_A = 0;    // ADC-A is released from reset
      
          AdcaRegs.ADCSOC0CTL.bit.ACQPS = 30;         // SOC0 will use sample duration of 30 SYSCLK cycles on ADC-A
          AdcaRegs.ADCSOC1CTL.bit.ACQPS = 30;         // SOC1 will use sample duration of 30 SYSCLK cycles on ADC-A
          AdcaRegs.ADCSOC2CTL.bit.ACQPS = 30;         // SOC2 will use sample duration of 30 SYSCLK cycles on ADC-A
          AdcaRegs.ADCSOC3CTL.bit.ACQPS = 30;         // SOC3 will use sample duration of 30 SYSCLK cycles on ADC-A
      
          //--- Configure the ADC-A base registers
          AdcaRegs.ADCCTL1.all = 0x0004;      // Main ADC configuration
      
          AdcaRegs.ADCCTL2.all = 0x000E;      // ADC-A clock configuration
      
          AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;          // Power up the ADC-A
      
          DELAY_US(1000);                             // Delay for 1ms to allow ADC time to power up
      
          AdcaRegs.ADCINTSEL1N2.bit.INT1E = 0;        // Disable INT1 flag
      
          AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 0;     // No further ADCINT1 pulses are generated until ADCINT1 flag (in ADCINTFLG register) is cleared by user.
      
          AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 3;      // EOC3 is trigger for ADCINT1
      
          AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 1;        // ADCINT1 will trigger SOC0 on ADC-A
          AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 1;        // ADCINT1 will trigger SOC1 on ADC-A
          AdcaRegs.ADCINTSOCSEL1.bit.SOC2 = 1;        // ADCINT1 will trigger SOC2 on ADC-A
          AdcaRegs.ADCINTSOCSEL1.bit.SOC3 = 1;        // ADCINT1 will trigger SOC3 on ADC-A
      
          AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;          // SOC0 will convert pin A0 on ADC-A
          AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;          // SOC1 will convert pin A1 on ADC-A
          AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;          // SOC2 will convert pin A2 on ADC-A
          AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;          // SOC3 will convert pin A3 on ADC-A 
      
          EDIS; /* Disable Write Access to Protected Registers */
      }

      void main(void)
      {
      int result1, result2, result3, result4, result5, result6, result7, result8 
      
      //
      // Step 1. Initialize System Control:
      // PLL, WatchDog, enable Peripheral Clocks
      // This example function is found in the F2837xD_SysCtrl.c file.
      //
          InitSysCtrl();
      
      //
      // Step 2. Initialize GPIO:
      // This example function is found in the F2837xD_Gpio.c file and
      // illustrates how to set the GPIO to it's default state.
      //
          InitGpio(); // Skipped for this example
      
      //
      // Step 3. Clear all interrupts and initialize PIE vector table:
      // Disable CPU interrupts
      //
          DINT;
      
      //
      // Initialize the PIE control registers to their default state.
      // The default state is all PIE interrupts disabled and flags
      // are cleared.
      // This function is found in the F2837xD_PieCtrl.c file.
      //
          InitPieCtrl();
      
      //
      // Disable CPU interrupts and clear all CPU interrupt flags:
      //
          IER = 0x0000;
          IFR = 0x0000;
      
      //
      // Initialize the PIE vector table with pointers to the shell Interrupt
      // Service Routines (ISR).
      // This will populate the entire table, even if the interrupt
      // is not used in this example.  This is useful for debug purposes.
      // The shell ISR routines are found in F2837xD_DefaultIsr.c.
      // This function is found in F2837xD_PieVect.c.
      //
          InitPieVectTable();
      
      //
      // Configure the ADC and power it up
      //
          Init_Adc();
      
      
      //
      // Enable global Interrupts and higher priority real-time debug events:
      //
          EINT;  // Enable Global interrupt INTM
          ERTM;  // Enable Global realtime interrupt DBGM
      
      
      //
      // take conversions indefinitely in loop
      //
          do
          {
              //
              //enable ADCINT flags
              //
      	EALLOW;
              AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;
              AdcaRegs.ADCINTFLGCLR.all = 0x0001;
      	EDIS;
      
              //
              //software force start SOC0 to SOC3
              //
              AdcaRegs.ADCSOCFRC1.all = 0x000F;
      
             //wait for ADC-A to complete, then acknowledge flag
             //
             while(AdcaRegs.ADCINTFLG.bit.ADCINT1 == 0);
             AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
      
             result1 = ((AdcaResultRegs.ADCRESULT0 >> 4) );
             result2  = ((AdcaResultRegs.ADCRESULT1 >> 4) );
             result3 = ((AdcaResultRegs.ADCRESULT2 >> 4) );
             result4 = ((AdcaResultRegs.ADCRESULT3 >> 4) );
      
             //wait for ADC-A to complete, then acknowledge flag
             //
             while(AdcaRegs.ADCINTFLG.bit.ADCINT1 == 0);
             AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
      
             result5 = ((AdcaResultRegs.ADCRESULT0 >> 4) );
             result6  = ((AdcaResultRegs.ADCRESULT1 >> 4) );
             result7 = ((AdcaResultRegs.ADCRESULT2 >> 4) );
             result8 = ((AdcaResultRegs.ADCRESULT3 >> 4) );
      
              //
              //disable ADCINT1 flag to stop sampling
              //
      	EALLOW;
              AdcaRegs.ADCINTSEL1N2.bit.INT1E = 0;
      	EDIS;
      
              //
              //software breakpoint, hit run again to get updated conversions
              //
              asm("   ESTOP0");
          }while(1);
      }

      But he software stop before the line in bold. i think the second conversion doesn't start.Why?

    Thank you.

  • Hi Electrocc,

    We're getting too many disparate questions in the same thread (we assign and service the e2e threads based on the part# and IP).  Can you make a new thread for the GPIO question and the question about the F2812 ADC?

    For the ADC code, does the sequence work once (to the first ESTOP) or it never reaches the breakpoint?

    Your ADC configurations seem correct based on a cursory look.  

    You may want to look at the ADC registers in the expressions window to see if all the configurations made it through though. In particular, I'm suspicious of the delay function you call in the middle of your configurations;  you should not call any other functions in an EALLOW/EDIS block as the function could modify the access settings.     

  • Hi Devin,

    Instead of opening a new thread, we will proceed step by step ; first, the ADC.

    The issue described above is solved. After rebooting my laptop and the control card, conversion now start each time.

    But do I need to use these lines after a conversion, like with the F2812?

    Software wait = (HISPCP*2) * (ADCCLKPS*2) * (CPS+1) cycles
    //               = (1*2)      * (3*2)        * (0+1)   = 12 cycles
    asm(" RPT #12 || NOP");

    Regards,



  • Hi electrocc,

    If the ADC is in late interrupt mode, then once the ADCINT flag goes high, the last result is ready to be read immediately.  You would usually want to use this mode, especially if you are using a spin-wait loop and not an ISR.  

    If the ADC is in early interrupt mode, then you may need to add some delay.  The max delay you would need is about 10.5 ADCCLKs (in 12-bit mode).  You can determine the exact timings via the ADC timings table in the datasheet.  You can subtract the time needed to read the other 3 results (probably the best way to determine this time would be via the profiler in CCS).   If you were using an ISR, you could also subtract the ISR latency.

  • Hi Devin,

    Thanks for your answer.

    Can you just confirm me one point : I want to calculate the duration of a converting sequence.
    If I use 12-bit Mode in Early Interrupt Mode, 4 signals to convert (SOC0 to SOC3 on ADC-A), duration is :

    T = (Acquisition Time + Convert Time) * 4 channels
    with Acquisition Time = SYSCLK * (ACQPS + 1)
           Convert Time = 10,5 ADCCLK

    Is it right?

    Thank you.

  • Hi Electrocc,

    Yes, that is roughly the time, but for the exact time see the timing diagrams in the datasheet:

    http://www.ti.com/document-viewer/TMS320F28377D/datasheet/adc-timings-in-12-bit-mode-sysclk-cycles-spruhm89183#spruhm89183

    This will tell you the delta between trigger and the first S+H starting as well as the exact number of SYSCLK cycles for the conversion phase (it is approximately 10.5 ADCCLKs, but it varies slightly based on the SYSCLK to ADCCLK divider selected).

  • Thanks,

    So if I want to reduce time for the converting sequence, is it the good way to use the 4 ADCs, but only SOC0?
    Normally time will be reduced by 4?

    Regards,

  • Hi Electrocc,

    Yes, in general you would fill up SOC0 slot on all 4 ADCs and use them in parallel before using SOC1 on any of the ADCs.  This will be much faster since the SOCs will convert in parallel.  You'll typically want to set the S+H to the longest S+H needed by all 4 SOC0s so that the ADCs will run in lock-step.  

  • Thank you very much, I'll do the test tomorrow and I'll let you know.

    To close this topic, do you have any idea concerning my issue with GPIO?
    If I use GPIO C, I have to disable pull-up to use, for example, GPIO74 as an input.

    Regards,

  • What happens if you dont disable the pull-up?

  • Hi Nima,

    If I don't disable pull-up, I have always a high level on GPIO74 (debug mode), even if I send a low level.

  • There is nothing different for GPIO74.

    1. The GPIO pull up is disabled by default

    2. If you are using the GPIO as input:

    • Configure the pin as GPIO by setting the MUX
    • Configure the GPIO as input (direction)

    3. Whether you enable or disable the pull up is based on your schematic and how your hardware is connected. Make sure the board is not adding any other signal to the path of your GPIO input.

    Also what do you mean by debug mode? when you dont have the debugger connected it works? I highly doubt any of this is relevant to your issue. 

    There is either code somewhere in your application that is changing your GPIO setting or the hardware connection to that specific GPIO has an element connected to it that you didnt expect.

    Nima Eskandari

  • Hi,

    You're probably right, I think it's an hardware issue.

    Thank you.

    Regards,