M4 gpio jitter

Discussion in 'UDOO NEO' started by sgygax, Sep 28, 2016.

Tags:
  1. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    Hi
    For driving some micro valves I need to generate pulses (no pwm!) with bitbanging.
    With the oscilloscope I see the pulsewidth with 500ns jitter.

    This is the test sketch:
    Code:
    #include <mqx.h>
    
    void setup() {
      pinMode(13, OUTPUT);
    }
    
    void loop() {
      while(1){
       _int_disable();
       digitalWrite(13, HIGH);
       digitalWrite(13, LOW);
       _int_enable();
       delay(10);
      }
    }
    
    Can anyone explain the jitter? Is there a solution to stop the jitter?

    Best regards
    Stefan
     
  2. waltervl

    waltervl UDOOer

    Joined:
    Dec 12, 2015
    Messages:
    2,314
    Likes Received:
    580
    First I am not an expert and did not use this yet. Using digitalwrite is not bit banging http://www.crash-bang.com/arduino-digital-io/

    So if the signal quality is this important you could investigate the arduino libraries on your Udoo and do real but banging by optimizing your code and don't use digitalwrite.
     
    Last edited: Sep 28, 2016
  3. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    Thanks for the answer! Below the new sketch. The output is faster put still has 400ns jitter.
    Code:
    #include <mqx.h>
    
    void setup() {
      GPIO4_GDIR|=(1U<<6); //pinMode(13, OUTPUT);
    }
    
    void loop() {
      while(1){  
        _int_disable();  
        GPIO4_DR|=(1U<<6);    //digitalWrite(13, HIGH);  
        GPIO4_DR&=(~(1U<<6)); //digitalWrite(13, LOW);
        _int_enable();
        delay(10);
      }
    }
    My applications normaly runs on a arm M4 mcu (Atmle, ST) without jitter.
     
  4. waltervl

    waltervl UDOOer

    Joined:
    Dec 12, 2015
    Messages:
    2,314
    Likes Received:
    580
    I am out of options......someone else? @jas-mx ?
     
  5. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    IMG_1070.JPG This is how the output signals looks like...
     
    Last edited: Nov 2, 2016
  6. tcmichals

    tcmichals Member

    Joined:
    Feb 25, 2015
    Messages:
    54
    Likes Received:
    27
    Remove the delay call and use a hard loop inside disable interrupts. This way no RTOS task switching will occur or ISR processing.
     
  7. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    I disable interrupt to do my output for a defined time...
     
  8. tcmichals

    tcmichals Member

    Joined:
    Feb 25, 2015
    Messages:
    54
    Likes Received:
    27
    Current Code:
    void loop() {
    while(1){
    _int_disable();
    GPIO4_DR|=(1U<<6); //digitalWrite(13, HIGH);
    GPIO4_DR&=(~(1U<<6)); //digitalWrite(13, LOW);
    _int_enable(); <-- enable interrupts
    delay(10); <-- delay, RTOS is running
    }
    }
    New Code:

    void _hw_delay(uint32_t delay)
    {
    //poll a timer
    }

    void loop() {
    _int_disable();
    while(1){
    GPIO4_DR|=(1U<<6); //digitalWrite(13, HIGH);
    GPIO4_DR&=(~(1U<<6)); //digitalWrite(13, LOW);
    _hw_delay(10);
    }
    _int_disable();
    }
     
  9. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    Thank you for the code...

    My delay() can be unstable, I don't care about that.
    What I'm pointig out is the time between _int_disbale() and _int_enable(). This time is not always the same (jitter)!
    See my oscilloscope picture...
     
  10. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    If we solve this "udoo neo" comes par with Beaglebone concerning Realtime...
     
  11. tcmichals

    tcmichals Member

    Joined:
    Feb 25, 2015
    Messages:
    54
    Likes Received:
    27
    Might be an issue with using DDR for instructions, maybe load the code into I-TCM and execute, see if the timing changes.
     
  12. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    Thank you! Good idea, is it possibel to do that in a sketch?
     
  13. jas-mx

    jas-mx Active Member

    Joined:
    Dec 31, 2013
    Messages:
    407
    Likes Received:
    118
    You should try toggling the gpio pin from within inside an interrupt handler eg the epit would be a good option (not from a sketch). If you still see the jitter then you may need to review the IOMUX configuration (output characteristics) of the pin to see if you can reduced the switching noise.
     
  14. tcmichals

    tcmichals Member

    Joined:
    Feb 25, 2015
    Messages:
    54
    Likes Received:
    27
    Yes looking at the code _int_disable:
    The _int_disable() function disables all hardware interrupts at priorities up to and including the MQX disable-interrupt level

    So, there can be other interrupts still active. Could do a:
    #define _ENABLE_ISR(x) __asm volatile ("cpsie i")
    #define _DISABLE_ISR(x) __asm volatile ("cpsid i")

    For testing only
     
    Last edited: Oct 5, 2016
  15. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    Thank you, I've already tried this. It's still the same.
     
  16. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    See the sketch with IOMUX configuration:
    Code:
    #include <mqx.h>
    
    void setup() {
      // iomuxc
      #define GPIO4_SPEED (3U<<6) /* 0..3 = 50mhz, 100mhz, 100mhz, 150mhz */
      #define GPIO4_DSE   (7U<<3) /* 0..7 = hiz, 260r, 130r, 88r, 65r, 52r, 43r, 37r */
      #define GPIO4_SRE   (1U<<0) /* 0..1 = slow, fast */
      IOMUXC_SW_PAD_CTL_PAD_NAND_DATA02=GPIO4_SPEED|GPIO4_DSE|GPIO4_SRE;
     
      //pinMode(13, OUTPUT);
      GPIO4_GDIR|=(1U<<6);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      while(1){
        _int_disable();
        //digitalWrite(13, HIGH);
        GPIO4_DR|=(1U<<6);
        //digitalWrite(13, LOW);
        GPIO4_DR&=(~(1U<<6));
        _int_enable();
       
        delay(10);
      }
    }
    It's still the same.
    I've also tried sketch with an interrupt handler and it was the same too.
    What do you mean by "not from a sketch"?
     
  17. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    It's now running from I-TCM and still the same...
     
  18. sgygax

    sgygax New Member

    Joined:
    Jul 22, 2016
    Messages:
    21
    Likes Received:
    0
    When I disable the timer GPT I have no more output jitter!
    But Linux does not work any more.
    Code:
    GPT_CR&=(~(1U<<0));
    Any comments on this?
     
  19. jas-mx

    jas-mx Active Member

    Joined:
    Dec 31, 2013
    Messages:
    407
    Likes Received:
    118
    The kernel is probably using the GPT internally, so disabling it isn't a good idea. You should launch your m4 code from uboot without starting the kernel to verify the linux side is affecting it.
     
  20. Andrea Rovai

    Andrea Rovai Well-Known Member

    Joined:
    Oct 27, 2014
    Messages:
    1,703
    Likes Received:
    240
    Hi there everybody,
    we've run the sketch and honestly we don't experience the problem.
    We've registered an impulse of about 250ns using the registers directly and an impulse of about 500ns using digitalwrite.
    This is the sketch we've used:

    void setup() {
    pinMode(13, OUTPUT);
    }

    void loop() {
    while(1){
    _int_disable();
    /*
    // ton = 272 nsec
    GPIO4_DR|=(1U<<6); //digitalWrite(13, HIGH);
    GPIO4_DR&=(~(1U<<6)); //digitalWrite(13, LOW);
    */

    // ton = 900 nsec
    digitalWrite(13, HIGH);
    digitalWrite(13, LOW);

    _int_enable();
    delay(10);
    }
    }
    The timing has been measured with the help of an oscilloscope.
     

Share This Page