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
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.
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.
Remove the delay call and use a hard loop inside disable interrupts. This way no RTOS task switching will occur or ISR processing.
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(); }
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...
Might be an issue with using DDR for instructions, maybe load the code into I-TCM and execute, see if the timing changes.
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.
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
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"?
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?
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.
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.