using teensy as a pattern generator

Status
Not open for further replies.

teensypulse

New member
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
 
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!
 
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!
 
Status
Not open for further replies.
Back
Top