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.

Using GPIO edge rising detect and DMTimer3 in EtherCAT project.

Other Parts Discussed in Thread: AM3359, SYSBIOS

Dear all,

I'm trying to use GPIO3 edge rising detect to trigger an interrupt and using DMTimer3 to call a function 0.1 microseconds in EtherCATproject.

I've followed those discussion below:
1.  http://e2e.ti.com/support/arm/sitara_arm/f/791/p/194331/695180.aspx#695180 

2.  https://e2e.ti.com/support/embedded/tirtos/f/355/t/270912 

Hwi_Params hwiParams;
Hwi_Handle myGPIOHwi;
Error_Block eb;
Error_init(&eb);
Hwi_Params_init(&hwiParams);
hwiParams.priority = 3;
hwiParams.arg = 62;
hwiParams.enableInt = FALSE;
/*62 int number-->GPIO3*/
myGPIOHwi = Hwi_create(62, GPIO_Isr, &hwiParams, &eb);
Hwi_enableInterrupt(62);     //SOC_GPIO_3_REGS
  if (myGPIOHwi == NULL)
    {
      System_abort("Hwi create failed");
    }

/*DMTimer initial*/

Timer_Params timerParams;
Timer_Handle myTimer;

DMTimer3ModuleClkConfig();

Timer_Params_init(&timerParams);
timerParams.period = 0.1;/*0.1 ms*/
timerParams.periodType = Timer_PeriodType_MICROSECS;
timerParams.arg = 1;
timerParams.extFreq.lo = 320000000;//32MHz
timerParams.extFreq.hi = 0;

myTimer = Timer_create(1, DMTimerIsr, &timerParams, NULL);  /* DMTIMER3 */

 if (myTimer == NULL)
   {
     System_abort("Timer create failed");
   }

/*The setup called from other .c file which I cooked it*/

DMTimerSetUp();
GPIOset();

Void Teninttask(UArg arg0, UArg arg1)
{
  while(1)
  {
   //GPIOPinIntEnable(GPIO_INSTANCE_ADDRESS,GPIO_INT_LINE_1,19);
     DMTimerIntEnable(SOC_DMTIMER_3_REGS, DMTIMER_INT_MAT_EN_FLAG | DMTIMER_INT_OVF_EN_FLAG);
     DMTimerEnable(SOC_DMTIMER_3_REGS);
  while(GPIOflagIsr == 0);
	{
	  for(i = 1; i <= 10; i++)
	{
	   while(DMTimerflagIsr == 0);

	   GPIOPinWrite(GPIO_INSTANCE_ADDRESS,20,GPIO_PIN_HIGH);

	   Delay(0xF);

	   GPIOPinWrite(GPIO_INSTANCE_ADDRESS,20,GPIO_PIN_LOW);

	   DMTimerIntEnable(DMTIMER_INSTANCE,DMTIMER_INT_MAT_EN_FLAG | DMTIMER_INT_OVF_EN_FLAG);

	   DMTimerflagIsr == 0;
	}
           GPIOflagIsr == 0;
	}
  }
}

At the result the program always hang on "while(GPIOflagIsr == 0);" seems it doesn's go in to the GPIO_isr.

The register is worked great.

The few questions below:

ØAre theose two initial way correct if yes why the function does'n get into isr? by the way, I've put the signal in to my input pin to trigger the gpio interrupt occur.

ØAre there have some rules to fallow between sys/bios to create initial function? If yes,then where should I put into the tiescutils.c and       how's the rule goes to ?
 

Thanks,

Tyler

  • Hi Tyler,

    A couple of questions...
    - Which device are you building this project for ?
    - What version of TI-RTOS or SYS/BIOS are you using ?
    - Which library do the GPIO aand DMTimer functions that you use belong to ?
    - I see you are using DMTimer APIs like DMTimerIntEnable(). Since you are using SYS/BIOS DMTimer module also, you need to be careful using other DMTimer APIs as they may conflict with BIOS.

    One problem I noticed is that you are assigning a floating point value (0.1) to an integer "timerParams.period" in the DMTimer initialization code. One other thing I wanted to mention is that "GPIOflagIsr" should be declared as volatile. I hope that is the case otherwise sometimes the compiler may optimize and not read the new value.

    Best,
    Ashish
  • Hi Ashish,

    Sorry for not to mention my device and SYS/BIOS.

    Here comes the follow:

    Device:   Am3359 ICE V2

    SDK   :    am335x_sysbios_ind_sdk_1.1.0.6

    BIOS :    bios_6_42_02_29

    XDC  :    xdctools_3_30_06_67_core

    CCS :    Code Composer Studio 6.0.0

    And I know what you mean for, you are worried about the ''GPIOflagIsr'' is not declared in volatile, so the compiler cannot get the value from the memory, the compiler just get  the value from the declared value ''GPIOflagIsr = 0 '' .

    I have declared the ''GPIOflagIsr'' in volatile the declared will goes to be like ''volatile unsigned int GPIOflagIsr = 0'' and the other declared ''DMTimerflagIsr = 0'' also in the same type.

    I will go to check the conflict problem.

    I have found that the function ''timerParams.period'' need to put the Uint32 in it,so is there any way to create a timer and it can able to call a function in every 0.1 millisecond(I have done that great in the example dmtimerCounter project)?  

    This is the library include.

    Thank you for your reply.

    Tyler

  • Hi Tyler,

    Tyler_yeh said:

    I have found that the function ''timerParams.period'' need to put the Uint32 in it,so is there any way to create a timer and it can able to call a function in every 0.1 millisecond(I have done that great in the example dmtimerCounter project)?  

    0.1 ms is 100 us (micro secs). So you can do the following:

    timerParams.period = 100;/* 0.1 ms or 100us */
    timerParams.periodType = Timer_PeriodType_MICROSECS;

    Best,

    Ashish

  • Hi Ashish,

    Through the days of debugging, discussion with my classmates and your help the timer is work good!

    My code struct can be divided by 3 part.

    i.  First one part is my initial part,I put the basic setting for DMTimer3 and GPIO3 in the void task1(); for example, like timer's      
        DMTimerCompareSet();...etc or in GPIO3 pinmux .....

    ii. At the second part I called interrupt initial part , I put the interrupt initial in the common main, for example,like

    Timer_Params timerParams;
    Timer_Handle myTimer;

    DMTimer3ModuleClkConfig();

    Timer_Params_init(&timerParams);
    timerParams.period = 100;/*0.1 ms單位是microsecs*/
    timerParams.periodType = Timer_PeriodType_MICROSECS;
    timerParams.arg = 1;
    timerParams.extFreq.lo = 320000000;//32MHz
    timerParams.extFreq.hi = 0;

    myTimer = Timer_create(1, DMTimerIsr, &timerParams, NULL); /* DMTIMER3 */

    if (myTimer == NULL)
    {
    System_abort("Timer create failed");
    }

    iii. And in the third part I called Function doing part, I put the doing function in the ''void APPL_Application(void)'' like the code below.

    for(i = 1;i <= 40;i++)
    {
    while(DMTimerflagIsr == 0);

    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,20,GPIO_PIN_HIGH);
    Delay(0xf);
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,20,GPIO_PIN_LOW);

    //DMTimerIntEnable(DMTIMER_INSTANCE,DMTIMER_INT_MAT_EN_FLAG | DMTIMER_INT_OVF_EN_FLAG);
    DMTimerflagIsr = 0;
    }   

    I think that have two ways to initial the interrupt.

    1. Hwi_

    2.Timer_

    The first one I was failed. I don't know why. The scope shows me that  the timer interrupt is working find but between the high and low signal there have many highly frequency signals, I can't figure out what happened.

    Like this:

    fig(1)

    From the pic we can find that between two high and low signal there have many highly frequency signals.

    The second one is working great.

    But have a little promlem.

    fig(2)

    We can see the first one timer interrupt have mismatch in every 100us.

    Some problems:

    Could you tell me why may be caused the highly frequency signal between high low signal in the fig(1)?

    In the fig(2) I thank that may be the priority or the timer counter problem??

    P.S.

    I didn't use the GPIO interrupt but I got the result I wanted.

    The green line is represent sync0 signal.

    All the operation is working under DC mode(twincat).

    Thank you for your reply.

    Tyler

  • Hi Tyler,

    I dont see fig1. Maybe it did not get uploaded ?

    Tyler_yeh said:

    I think that have two ways to initial the interrupt.

    1. Hwi_

    2.Timer_

    The first one I was failed. I don't know why. The scope shows me that  the timer interrupt is working find but between the high and low signal there have many highly frequency signals, I can't figure out what happened.

    What are you exactly doing in the first (Hwi) approach ?

    Tyler_yeh said:

    We can see the first one timer interrupt have mismatch in every 100us.

    Some problems:

    Could you tell me why may be caused the highly frequency signal between high low signal in the fig(1)?

    In the fig(2) I thank that may be the priority or the timer counter problem??

    What did you mean by mismatch here. Is the timer period not 100us as it was suppose to be ?

    Best,

    Ashish

  • Hi Ashish,

         Sorry I count not reply as soon as possible because of the midterm at the last week.

    At the beginning I would like to tell you about some mistakes in my last reply.

    I mixed up two declared(Hwi & Time). 

    So friend, u just look up the depiction below,

    Ok,

         The fig (1)

                            

    I am using "Time_" package to initial the DMTimer3.

    Here comes the code

    Timer_Params timerParams;

    Timer_Handle myTimer;

    DMTimer3ModuleClkConfig();

    Timer_Params_init(&timerParams);

    timerParams.period = 100;                /*0.1 ms單位是microsecs*/

    timerParams.periodType = Timer_PeriodType_MICROSECS;

    timerParams.arg = 1;

    timerParams.extFreq.lo = 320000000;      /*32MHz*/

    timerParams.extFreq.hi = 0;

    myTimer = Timer_create(1, DMTimerIsr, &timerParams, NULL); /* DMTIMER3 */

    if (myTimer == NULL)
      {
         System_abort("Timer create failed");
      }

    At the moment I count't figure out what happened with the fig(1)!!

    DTMtimer3 was working perfect and calling the function at every 100us, but we looking at the fig(1) there had highly frequency between 100us. 

    Finally I found the problem, because I also declare the frequency in the app.cfg file.

    Like this,

    /* set the Timer frequency to 32KHz */
    //var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
    //Timer.intFreq.hi = 0;
    //Timer.intFreq.lo = 32768;//32768

    So the GPIO maybe output two signal together.

    Later I mark those function the fig(1) is working find!:)   Yes!

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    From the topic, I want to use the sync0 signal to be an input signal and by using the GPIO3 edge rising detect to make an interrupt and this interrupt will trigger DMTimer3 to call the function every 100us(under the DC-Synchron and the DC signal is 4ms).

    My code (in ecat_appl project and those code below are writed down in the tiescappl.c):

    void APPL_Application(void)
    {

    /*dmtimer3*/
    Hwi_enableInterrupt( 69 );


    /*GPIO3*/
    Hwi_enableInterrupt( 62 );


    GPIOPinIntEnable(SOC_GPIO_3_REGS,GPIO_INT_LINE_1,19);
    DMTimerIntEnable(SOC_DMTIMER_3_REGS, DMTIMER_INT_MAT_EN_FLAG | DMTIMER_INT_OVF_EN_FLAG);

    while(GPIOflagIsr == 1)
    {
        DMTimerEnable(SOC_DMTIMER_3_REGS);


        for(i = 1;i <= 40;i++)
            {
               while(DMTimerflagIsr == 0);


               DMTimerCounterSet(SOC_DMTIMER_3_REGS, 0x0000001F);


               GPIOPinWrite(GPIO_INSTANCE_ADDRESS,20,GPIO_PIN_HIGH);


               Delay(0xf);


               GPIOPinWrite(GPIO_INSTANCE_ADDRESS,20,GPIO_PIN_LOW);


               DMTimerflagIsr = 0;
            }

    GPIOflagIsr = 0;
    }

    ........

    }

    The scope shows some pictures for me.

    The green line is sync0's signal and the yellow is GPIO's signal.

    Every sync0's signal between each other is 4ms.

    Every GPIO's signal between each other is 100us.

    But after four sync0 signal we could see the ''gap'' between fore and five.

     We take a little bit zoom in to the red squre.

    We could see there having a yellow signal over the sync0 signal and unfortunately that cause the gpio edge rising detect couldn't detect anything.

    What I want?

    I want there have 40 interrupt between two sync0 signal in 4ms.

    What I try?

    1. I have already done this issue great in the dmtimercounter project so the hardware could make it.

    2. I have try different way to initial the DMTimer3 (Hwi_ and Timer_) but get the same result.

    My question.

    1. I think there has several functions needed to execute after the while loop(for example "main loop") and caused the problem.
        But when I test 39 interrupts between two sync0 signal it will be find. 
        So would you have some suggestions for me to try?

  • Could anyone help me?
  • Hi Tyler,

    You might be seeing the "gap" because an interrupt is occurring and pre-empting the while loop that is toggling the GPIO pin. You may want to try disabling the SYS/BIOS clock. If you do so, you cannot use Task_sleep() or use the timeout feature of any kernel APIs.

    Best,

    Ashish

  • Hi Ashish,

    Thanks for your reply.

    I didn't know what you mean.You said that disable the SYS/BIOS clock and the function Task_sleep() or kernel APIs will can't be used too,but the function Task_sleep() and some kind of kernel APIs are through around the EtherCAT project.

    Could you tell me more details for that? Thank you.

    Priority: Timer 11  
                    GPIO 12  
                    ADC  10

    I think the gap is coming from the "delay"(EtherCAT state check or something else like Hw_GetTimer(),ECAT_CheckTimer(),bsp_getlocal_sys_time...etc).

    The delay is cumulatively,then if the delay is big enough it will let the final interrupt exceed the next sync0 signal,and caused the GPIO interrupt detect for nothing.

    So the nothing is so called "gap". 

    green line = sync0 signal

    yellow dotted line = GPIO high & low (which called from the interrupt)

    6us-->48us-->88us = ( "delay" )

    The red dotted line it should be part of one between 3 & 4 section,but the delay caused it out of 3 & 4 section.

    By the way I try other ways to solve this gap problem, but failed.

    I figure out three ways.

    1. Put the program in the Sync_Isr to avoid the delay.           Fail.

    2. I add "if break" in my program.(If detect the sync0 signal then break).    Fail.



     Hwi_enableInterrupt( 69 );

     Hwi_enableInterrupt( 62 );
     GPIOPinIntEnable(SOC_GPIO_3_REGS,GPIO_INT_LINE_1,19);
     DMTimerIntEnable(SOC_DMTIMER_3_REGS, DMTIMER_INT_MAT_EN_FLAG | DMTIMER_INT_OVF_EN_FLAG);

     while(GPIOflagIsr == 1)
              {
                  GPIOPinIntDisable(SOC_GPIO_3_REGS,GPIO_INT_LINE_1,19);
                  GPIOPinIntClear(SOC_GPIO_3_REGS,GPIO_INT_LINE_1,19);
                  GPIOflagIsr = 0;
                  GPIOPinIntEnable(SOC_GPIO_3_REGS,GPIO_INT_LINE_1,19);
                  DMTimerEnable(SOC_DMTIMER_3_REGS);
                  DMTimerCounterSet(SOC_DMTIMER_3_REGS, 0x0000001F);

                  for(i = 1;i <= 40;i++)
                      {
                         while(DMTimerflagIsr == 0);
                         DMTimerCounterSet(SOC_DMTIMER_3_REGS, 0x0000001F);
                         GPIOPinWrite(SOC_GPIO_3_REGS,20,GPIO_PIN_HIGH);
                         Hwi_enableInterrupt(SYS_INT_ADC_TSC_GENINT);
                         /* Enable step 1 */
                         TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 1, 1);
                         while(flagADC);
                         /* Enable step 2 */
                         TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 2, 1);
                         while(flagADC);
                         /* Enable step 3 */
                         TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 3, 1);
                        while(flagADC);
                        /* Enable step 4 */
                         TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 4, 1);
                        while(flagADC);
                        /* Enable step 5 */
                         TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 5, 1);
                        while(flagADC);
                        /* Enable step 6 */
                         TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 6, 1);
                        while(flagADC);
                        /* Enable step 7 */
                         TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 7, 1);
                        while(flagADC);

                        sample1 = TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
                        sample2 = TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
                        sample3 = TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
                        sample4 = TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
                        sample5 = TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
                        sample6 = TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
                        sample7 = TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);

                        sAI1Inputs.AN_1 =(Int32) sample1;
                        sAI1Inputs.AN_2 =(Int32) sample2;
                        sAI1Inputs.AN_3 =(Int32) sample3;
                        sAI1Inputs.AN_4 =(Int32) sample4;
                        sAI1Inputs.AN_5 =(Int32) sample5;
                        sAI1Inputs.AN_6 =(Int32) sample6;
                        sAI1Inputs.AN_7 =(Int32) sample7;

                        flagADC = 1;
                        if(GPIOflagIsr == 1)break;
                        GPIOPinWrite(SOC_GPIO_3_REGS,20,GPIO_PIN_LOW);
                        DMTimerflagIsr = 0;
                      }

                    GPIOflagIsr = 0;

             }

     I got the same result from this post in the beginning.

     

    3. I increasing my interrupt GPIO high & low to 80 and we take the odd part. This action equal to take 40 interrupts.

    The tickfunction period be came to 0.05us.

    But I got the same result.

    From now I have not ideal to solve it.

    Could you give me some suggests?

    Thank you so much.

    Best,

    Tyler

  • Hi Tyler,

    This thread has gotten quite long so I need to clarify some things.

    - Your main issue is that the GPIO signal you are generating by toggling the GPIO pin (Port 3 pin 20 ?) stops briefly resulting in a Gap ?
    - The Sync0 signal is being generated using the DMTimer ? Can you share the DMTimer and GPIO interrupt handler code ? It would be better if you could share the entire project.

    Best,
    Ashish
  • Hi Ashish,

    Thanks you for your reply.

    - Your main issue is that the GPIO signal you are generating by toggling the GPIO pin (Port 3 pin 20 ?) stops briefly resulting in a Gap ?

    Yes.

    - The Sync0 signal is being generated using the DMTimer ?

    No,I put my code in the "void APPL_Application(void)" and the Sync0 is generated from the TwinCAT by my pc.

    More details I would like you to watch my .c files.

    Thanks you.

    1348.tiescutils.c

    7103.tiescappl.c

    1538.timer.c

    Best,

    Tyler