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.

Ethernet send() function interferes with GPIO

Other Parts Discussed in Thread: SYSBIOS

Equipment:

            ICEv2 board,

            CCSv6 vs 6.0.1.00040,

            TI XDS100v2 USB Emulator,

            Windows7,

            am335x_sysbios_ind_sdk_1.1.0.6

            NDK 2.24.1.18

            NDK's NSP 1.10.2.09 not activated

            SYSBIOS 6.40.3.39

            Compiler TI v5.1.11

            Project: 'standalone Ethernet switch' derived from the EthernetIp example of the SDK,

                         PRUSS for Ethernet access

 

 

Hi everybody,

 as a result of some modifications (cache enabled, peripheral address range set to bufferable), I managed to create bursts of  ten 40ns-pulses periodically.

The pulses are created like this:

       asm (" MOVT r3, #0x08");   // load, Bit19=1

       asm(" STR R3,[R1]");       // write --> HIGH

       asm (" MOVT r3, #0x00");   // load, Bit19=0

       asm(" STR R3,[R1]");       // write --> LOW

This code runs in a timer-ISR, i.e. interrupts are not explicitly enabled and all 10 pulses are generated one after the other.

Everything is ok: bursts of ten pulses (40ns high, 40ns low for each period). 

 

But as soon as periodic data transfer via TCP/IP (which does NOT happen simultaneously to pulse generation!) is switched on, bursts occasionally look like this:

I.e. the length varies, it is not constant any longer. (Pulses are ok. if the send() function is commented out.)

In my understanding, an ISR cannot be interrupted. But what then is the reason for that variation one can see on the scope?

Perhaps I should mention that TCP/IP transfer is realized using the PRUs (with the binary code that comes with the ethernetip example).

Does anybody have an explanation for this phenomenon?

 

Regards,

Martin H.

  • Martin,

    How about the priority of the timer ISR? The ethernet driver has an RX Interrupt which is of high priority, this can stall the servicing of the Timer ISR..

    Regards,
    Vinesh
  • Hi Vinesh,

    thanks for replying.

    I am not sure about the timer's priority. I did not create an Hwi-object to keep latency small.

    This is what I did:

      Timer_Handle hTimerT3 = NULL;

    Timer_Params timerParams3;
    ...
    Timer_Params_init(&timerParams3);
    timerParams3.period = 500;  // 0,5ms
    timerParams3.startMode = Timer_StartMode_USER;
    timerParams3.runMode = ti_sysbios_interfaces_ITimer_RunMode_ONESHOT; 
    ...
    Timer_start(hTimerT3);

    I would have expected that the timerParams3 struct contains a priority parameter, but there isn't.

    So I wonder where priority is specified. Can you give me a hint? I then might modify it and see if it makes any difference.

    Besides that I disabled HWI interrupt nesting in app.cfg, but most likely this is useless as an Hwi-object has not been created.

    Could my ISR really be preempted? It is not an Hwi.

    All comments are very much appreciated.

    Regards,

    Martin H.

  • Martin,

    Going with the priority suggestion.  When you create a Timer....it creates a Hwi underneath for you.  Now, you can set the Hwi_Params structure (which contains a priority field) in the timer params structure.  Another possible option you could try is....If you can determine which Hwi # was created for your Timer...You could can call Hwi_setPriority(intNum, priority) and try to raise the priority of your Timer interrupt.  You can do this by running your program to where you create the Timer and opening up the ROV plugin and viewing the Hwi module.

    Because this is a Hwi, yes, another Hwi can preempt it, unless you disable the autoNesting Support.  You can do in your *.cfg file:

    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    Hwi.dispatcherAutoNestingSupport = false;

    Judah

  • Hi Judah,

    autoNesting Support is disabled and additionally (unnessarily I should say) I added

    key = Hwi_disable() ….. Hwi_restore(key)

    to the ISR. But the square waves are not stable yet. Would you agree that preemption can be excluded as a reason for that distortion?

    On the other hand I would not mind setting a different priority to the timer ISR - just to see what happens. So if

                       hTimerT3 = Timer_create(3, (Timer_FuncPtr)TimingIsr, &timerParams3, &eb3);

    creates an HWI automatically (and it does not need to be done manually), how could the Hwi_Params structure be accessed?

    I ran the ROV after timer creation and got intNum = 93 and priority=63 for the timer in the HWI section. But invoking Hwi_setPriority(93, 40) after that did not change anything in the ROV. Is that the way it should be?

     Regards,

    Martin H.

  • Hi Judah, hi to everybody who is reading this thread,

    the problem of not finding the Hwi_Params structure in the Timer_Params structure was that I included <ti/sysbios/family/arm/a8/intcps/Hwi.h> instead of <ti/sysbios/timers/dmtimer/Timer.h>

     Without adding a Hwi_Params structure, ROV reports a priority of 63 for the timer and the RxInterruptHandler.

    Now I added a Hwi_Params structure to the Timer_Params structure and set priority to 20. Then the timer handle was created. ROV reports a priority of 20.  ( Hwi_setPriority(intNum, priority) could not be used as it is not contained in <ti/sysbios/hal/Hwi.h>)

     Now as 20 represents a higher priority than 63 I had expected that the problem would have gone. It still exists. (Setting timer priority to 65 didn’t help either.)

    Also hwiParam_Timing.maskSetting = Hwi_MaskingOption_ALL in the Hwi_Params structure to prevent preempting  was useless.

    Now what could be the reason for that interference with the GPIO?

    Does anybody have a new idea? It obviously has to do with the Ethernet as it comes up when the send() function is invoked periodically.

    All comments are very welcome!

    Regards,

    Martin H.

  • Martin,

    A couple of things to try:

    1.  Do not disable auto nesting support.  The reason is...If another ISR is executing, it will hold off your Timer ISR.

    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    Hwi.dispatcherAutoNestingSupport = true;

    2.  For your Timer ISR mask out all other ISRs.  (Seems like you are doing this already...it should not be useless since auto nesting is true now)

    3.  For the other ISRs, make sure they are not masking your Timer ISR.

    4.  Calling Hwi_disable/restore in your ISR is not necessary as interrupts are enabled by SYSBIOS before your ISR is called.

    If its still not working after this, then I cannot think of anything else to try at the moment via software.

    Judah

  • "4.  Calling Hwi_disable/restore in your ISR is not necessary as interrupts are enabled by SYSBIOS before your ISR is called."

    Wouldn't that be a reason to disable/restore HWI?

    Regards,

    Martin H.

  • Martin,

    What I'm trying to say is...Using Hwi_disable/restore in your ISR is too late because BIOS goes and enables global interrupts before we get to your ISR so doing this in your ISR is NOT going to prevent another interrupt from preempting the currently executed one...You aren't going to hold off any ISR that were triggered between your ISR being triggered and getting to your ISR function.

    YOu need to use the Hwi masks setting to do this.  The mask will prevent any ISR that you specified to be hold off until the current ISR finishes.

    Judah

  • Hi Juda,

    good to know though I did not expect this behaviour.

    I suppose you are right: Most likely it is a hardware problem. I will do another test as soon as I will have a new board. Hopefully this will lead to an improvement.

    Thanks for your support!

    Regards,

    Martin H.