Need a short pulse Propeller GCC
DarkGFX
Posts: 17
Hello, I have only tried some small projects with the propeller so I'm really new to this.
I'm trying to get a short pulse on pin 4 on the activity board, this needs to be *** short *** possible!
I have tried the waitcnt command but it seems to have problems with getting under microseconds limit.
I need this function to be in the nanosecond range, *** low *** possible!
I will need to control the off time and on time of the pin, and it need to be able to repeat X number of times.
Have configured the system clock to work at 80MHz.
I have written this function:
void flash_enable(int flash){
double t1, t2, diff;
for(int i = 1; i <= flash; i++){
high(4);
t1 = CNT;
__asm__ volatile (" nop\n nop\n");
t2 = CNT;
low(4);
diff = t2 - t1;
print("Diff %d\n", diff);
pause(1);
print("flash nr: %d\n",i);
}
}
But there is something strange with this one! I wrote something similar earlier and a got a diff of 15, I consider this delay to be 15*12.5 ns, but now its returning a really high number.
I guess its a lit better to write the whole code in ASM, but I'm not to familiar with that language.
I'm trying to get a short pulse on pin 4 on the activity board, this needs to be *** short *** possible!
I have tried the waitcnt command but it seems to have problems with getting under microseconds limit.
I need this function to be in the nanosecond range, *** low *** possible!
I will need to control the off time and on time of the pin, and it need to be able to repeat X number of times.
Have configured the system clock to work at 80MHz.
I have written this function:
void flash_enable(int flash){
double t1, t2, diff;
for(int i = 1; i <= flash; i++){
high(4);
t1 = CNT;
__asm__ volatile (" nop\n nop\n");
t2 = CNT;
low(4);
diff = t2 - t1;
print("Diff %d\n", diff);
pause(1);
print("flash nr: %d\n",i);
}
}
But there is something strange with this one! I wrote something similar earlier and a got a diff of 15, I consider this delay to be 15*12.5 ns, but now its returning a really high number.
I guess its a lit better to write the whole code in ASM, but I'm not to familiar with that language.
Comments
OUTA[4]~~ 'Make P4 high
OUTA[4]~ 'Make P4 low
To go faster would require either a PASM program or use of the counters.
your code would work, but I have not control over the delay, I cant change it to fit different purposes.
And this is what I want, but thanks for the reply!
Any chance I could talk you into a code example
I had to go away for a couple of days, so I did not have time to check the replies.
There is a lot of good suggestions here, I will try several of the suggestions today to see how fast these examples can execute a pulse.
Note the print commands I used in my code was not to measure exact time, I just used it as a reference value to see what used less time that other solutions I used. I have access to an oscilloscope, so I have the possibility to use this when the software measured time differential gets low enough.
I will also try to add the __attribute__((fcache)) to my function!
While I try the different suggestions above, can someone that knows ASM give me an good example of this as well with some comments so I can try to understand it.
As an exercise for me, and I guess to get this function reliable and really fast I guess I need to use ASM.
Best regards
Patrick
PS: Thanks for all the help so far, really appreciate it!!!
I tried to run your code with measuring of system clk before and after the PHSA command, the difference can not go below 64 clk cycles, witch is some of the best result I have gotten so far, but can we push it even lower??
I know that some of the clk cycles I measured is there due to the time t takes to execute the int = CNT command, but it is a good reference pint.
But a problem is the wait function waitcnt, unless I used a delay of 100000 clk pulses it would not run smooth, and this delay is to long.
My example of your code:
__attribute__((fcache))
void flash_enable2(int32_t flash)
{
int32_t counter;
// initialize this variable with an appropriate value
int32_t pulse_width = 1;
// initialize this variable with an appropriate value
int32_t delay = 100000;
// Set up the CTRMODE of Counter A for NCO/PWM single-ended.
CTRA = (4 << 26) | 4;
// Set the value to be added to PHSA with every clock cycle.
FRQA = 1;
// Set DIRA as an output.
DIRA |= 1 << 4;
// Get the current System Counter value.
counter = CNT;
for(int32_t i = 1; i <= flash; i++)
{
// Send out a high pulse on the desired pin for the desired duration.
int T1 = CNT;
PHSA = -pulse_width;
int T2 = CNT - T1;
print("diff= %d\n", T2);
// Wait for a specified period of time before sending another high pulse
waitcnt(counter += delay);
}
I must confess that understood very little of this, is it possible you could elaborate this a bit more?
But what if we use ASM, could we get full control of the ON_time and OFF_time of the pulse with reliable short delays with only a couple of ticks of the system clock?
I am not sure about this, but perhaps execution time could be cut a little more by changing
From:
To:
There are undoubtedly several examples of using NCO/PWM single-ended counters written in PASM, you just have to seek them out and perhaps modify the examples to suit your needs.
Over the years, I have read about several people trying to reach the nanosecond range. Perhaps a Google search of the forum, using "nano" and "counter" as search terms may yield some interesting results for you.
thanks for the loop optimization, I will need this at a later stage in my project.
My main concern right now is to get that first pulse as short as possible! And I will haft to take on the problem regarding how much time the loop requires at a later point.
I have tried to find a solution searing both the forum and google, but have not found a good example winch I at least can understand. This is why I'm reaching out to the forum.
But I will continue trying, I will not easily give up .
I have tried to read up in inline pasm, but I must admit its a bit hard to understand.
I was hoping that maybe a fast toggle with PASM could give me what I needed.
It would help alot if you give us more infos:
- What is the application
- Must the pulse times be variable or can they be fixed
- if variable: at compile time or at run time?
- must the number of pulses be variable at run time
- and most important: what is the range of the pulse times you need and with what resolution.
There are a number of solutions with the Propeller: C only, with PASM, with Counters, with VideoGenerator hardware ...
For example if you only need the shortest possible high pulse of 12.5ns and only need to make the low time variable, the the DUTY mode of a counter is a very simple solution: (This is untested and produces endless pulses)
Andy
The code prints 12 for the elapsed time, which includes 3 instructions: setting the pin high, setting it low, and the subtraction for elapsed time calculation. I think the pulse itself should be just 4 cycles, but I don't have an oscilloscope handy here to verify that.
Eric
I will answer the questions above here:
What I'm making requires an led to blink extremely fast and extremely bright, to do this I'm driving the led with around 10 times more current than it can handle, I'm going to use this to stop the moments of a moving bullet. In other words and building a fast led camera flash!
I know there is a lot of other circuits I could use to get the led to blink, but I want to use the propeller since it's going to do other operations as well.
- What is the application
The application is that at a given time, the controller should flash a led as fast as possible X-number of times. How the prototype works is that the Flash() function is called when I push a button.
How fast this flashes optimally should be I will need to experiment on. So that's why I need the pulse as fast as possible and yet variable.
- Must the pulse times be variable or can they be fixed
The pulse times will be fixed when I find the optimal time that will achieve what I want.
- if variable: at compile time or at run time?
They can be variable at compile time
- must the number of pulses be variable at run time
NO
- and most important: what is the range of the pulse times you need and with what resolution.
As short and fast *** possible!
Hi Eric
How do you get 12 ticks?
I get 144 without __attribute__((fcache)), and 28 with, am I using the wrong memory model or something?
I'm using LMM Main RAM.
Patrick
What optimization flags are you using? I used -Os.
I'm also using a recent build of the compiler (the 1.9.0_alpha series) rather than the one that comes with SimpleIDE. The SimpleIDE one is pretty old, and it may be missing some optimizations.
That might do the trick!
I'm using simple IDE and -O2 speed as optimization, I will search for the alpha series and try that one!
Thanks =D
full-on light to zero)? Bullet velocity? 750 - 4,000 ft/sec? At the velocity anticipated, how long will one pulse light-up the bullet? The answers should help to nail down specs for the pulse width, duty cycle and burst duration.
EDIT: Found some info about LED flashes used in cell phones:
"Agilent has developed high-brightness white LED light sources, the HSMW C830/C850 Agilent Flash Modules, which are specifically designed to suit the actual requirements of camera phone camera modules. Their unique dome design concentrates the light output from the LED die to form a 60-degree Lambertian radiation pattern, maximizing the light output that falls within a typical camera’s field of view. No secondary optics are needed to redirect the light output. Both major and minor axis produce similar radiation patterns. "
There's also a paper/pdf about the design of a circuit using these parts.