Forum Rule: Always post complete source code & details to reproduce any issue!
-
using teensy as a pattern generator
Hello,
I am trying to use Teensy as a very fast pattern generator. The pattern should be like ~us of pattern data and repetition rate of let say 50us.
In the past I used Arduino with the code something like this:
void setup() {
TIMSK0 = 0; // no interrupts
OCR0A = 0; // count to 2
DDRB = B00011100;
} // end of setup
// trigger 1 (port 11)
// pulse bit 2 (port 12)
// blanking 3 (port 13)
void loop()
{
double a;
PORTB = B00000000; // important to keep here
PORTB = B00000000; // important to keep here
PORTB = B00010000;
PORTB = B00010100; // ____||______
PORTB = B00010100; // __|------|___
PORTB = B00010100; // ________|---|_
PORTB = B00010000;
PORTB = B00011000; // pulse + protection
PORTB = B00010000;
PORTB = B00010000;
PORTB = B00010000;
PORTB = B00010000;
PORTB = B00000000; // important to keep here
PORTB = B00000000; // important to keep here
for(int i = 0; i <80; i++) // 50 us per 100 reps
PORTB = B00000000;
}
this worked fine, for the purpose, at the clock rate of imho 16MHz
Question - will I have any lack using this on Teensy architecture ? Can I reach clock rate of the chip with this approach ?
Thanks!!!
Boris
-
Senior Member+
No, on ARM, the GPIOs are connected on a internal BUS.With which speed it runs, depends on the Teensy-model and its settings. With Teensy 4 it's 150MHz.
So you can toggle a tight loop with while(1) {digitalWriteFast(0,1);digitalWriteFast(0,0);} at 150MHz / 2
this worked fine, for the purpose, at the clock rate of imho 16MHz
No, the CPU worked at the clockrate of 16MHZ. Your loop is much much much slower.
-
Thanks Frank! I made a quick test on TEENSY 3.2 and things look a bit iffy. The test is a two 'pulse' sequence:
void setup() {
//set pins to output
pinMode(13, OUTPUT);
}
int c = 1, r=0;
void loop(void) {
switch(c) {
case 1:
noInterrupts();
digitalWriteFast(13, LOW);
digitalWriteFast(13, LOW);
digitalWriteFast(13, LOW);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, LOW);
digitalWriteFast(13, LOW);
digitalWriteFast(13, LOW);
digitalWriteFast(13, LOW);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, HIGH);
digitalWriteFast(13, LOW);
digitalWriteFast(13, LOW);
digitalWriteFast(13, LOW);
interrupts();
break;
case 2:
.... the same like 1 but more LOW writes in the middle
case 3:
.... the same like 2 but more LOW writes in the middle
}
if(r > 1000) {
if(c==3) c=1;
else c++;
r = 0;
}
else r++;
delay(5);
}
the result of the test - the first 'pulse' of HIGH's is different between cases (case 1: 72ns, case 2: 164ns, case 3: 72ns, very reproducibly, second pulse is ~40ns). So overall it is hard to predict what exactly will be generated.
any advise ?
Thanks again!
-
Senior Member+
Not really
Just guessing.. the flash access might influence things.
Maybe try to make a function with "fastrun" for every pattern:
Code:
FASTRUN void pattern1(void) {
noInterrupts();
do {
digitalWriteFast(....
} while (r<1000);
interrupts();
....
...sorry, a blind guess, not sure if it is better.
Or (and) save the pattern in a array:
uint8_t pat1[200] = {0,0,1,1,1,1,0,.... <-don't use const here to make sure data are in RAM
FASTRUN pattern
do...
.. digitalWriteFast(13, pat1[i++]);
while ...
-
FASTRUN seems working - need more testing
running through the array is stable but slow (80ns per array element)
Thanks!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules