Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: Modifying my source code for Teensy

  1. #1
    Junior Member
    Join Date
    Mar 2019
    Posts
    7

    Modifying my source code for Teensy

    I've just got lost in the manuals for the MKL26Z64VFT4 and wondered if anyone her could help?

    The code here is for the Arduino nano. It needs to work in a microsecond or so and so I've bypassed the normal Digitalread and digital write commands and addressed the digitalread port DDRD and then written to Port D with a binary command.

    The teensy is much faster but doesn't like DDRD, etc, because it's specific to the arduino's chip.

    So I need to do a similar thing on the teensy, but how do I set up an interrupt and find the commands for addressing the ports without reading the 600 page manual?

    Ed


    /*

    */

    // This code is to take an input from pin D2 and output Rx blank on D3 which has a 2us delay on the falling edge and output Tx blank on D4 which has a 2us delay on the rising edge.


    const byte interruptPin = 2;
    volatile byte state = 0b00000000;
    const byte rise_delay =6;
    const byte fall_delay = 5;

    void setup() {
    //setup port D pins 3 and 4 as outputs. Pin 3 = RX_blank; Pin 4 = TX_blank//
    DDRD = DDRD|B00011000;
    //start with interrupt on rising edge//
    attachInterrupt(digitalPinToInterrupt(interruptPin ), rise, RISING);
    }

    void loop() {
    // loop goes on forever with no actions so interrupts are serviced on rising and falling edges//


    }

    void rise() {
    //Delay TX blank after rising edge//
    //turn on Rx_blank//
    PORTD=0b00001000;
    //turn on Tx_blank as well//
    delayMicroseconds(rise_delay);
    PORTD=0b00011000;
    detachInterrupt(digitalPinToInterrupt(interruptPin ));
    attachInterrupt(digitalPinToInterrupt(interruptPin ), fall, FALLING);
    }

    void fall() {
    //delay Rx_blank after falling edge//
    PORTD=0b00001000;
    delayMicroseconds(fall_delay);
    PORTD=0b00000000;
    detachInterrupt(digitalPinToInterrupt(interruptPin ));
    attachInterrupt(digitalPinToInterrupt(interruptPin ), rise, RISING);
    }

  2. #2
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,565
    just try digitalReadFast/digitalWriteFast - you will be surprised how fast it is - esp. if you're using it with a const pin number.

    edit; I see you're using delays anyway - so what's the point to use direct port access?
    Last edited by Frank B; 03-08-2019 at 09:58 AM.

  3. #3
    Junior Member
    Join Date
    Mar 2019
    Posts
    7

    Modifying my source code for Teensy

    Quote Originally Posted by Frank B View Post
    just try digitalReadFast/digitalWriteFast - you will be surprised how fast it is - esp. if you're using it with a const pin number.

    edit; I see you're using delays anyway - so what's the point to use direct port access?
    I have a read input on port 2 and I want a 2us delayed output on port 3. On the Arduino I get the 2us delay but an additional 3us delay from the micro.

    I got my code converted for the Teensy but it looks like the problem is I have is that I am using the Teensy LC which has a 16MHz clock (according to a schematic I found on the internet). I thought I was running at 48MHz and so would be 3 times as fast.

    What I am trying to do is to delay my rising edge by a delay.

  4. #4
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,565
    it uses a PLL for the clock an indeed runs with 48MHz

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,920
    This might be a case where something simple & easy becomes quite a challenge by "overthinking".

    I ran copy of your code here, with the AVR port stuff replaced by digitalWriteFast, and a PWM signal to generate the interrupt pulse for testing.

    Code:
    const byte interruptPin = 2;
    volatile byte state = 0b00000000;
    const byte rise_delay = 6;
    const byte fall_delay = 5;
    
    void setup() {
      // PWM waveform - connect to pin 2 for testing
      analogWriteFrequency(23, 1000);
      analogWrite(23, 4);
      //setup port D pins 3 and 4 as outputs. Pin 3 = RX_blank; Pin 4 = TX_blank//
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      digitalWriteFast(3, LOW);
      digitalWriteFast(4, LOW);
      //start with interrupt on rising edge//
      attachInterrupt(digitalPinToInterrupt(interruptPin ), rise, RISING);
    }
    
    void loop() {
      // loop goes on forever with no actions so interrupts are serviced on rising and falling edges//
    }
    
    void rise() {
      //Delay TX blank after rising edge//
      //turn on Rx_blank//
      digitalWriteFast(3, HIGH);
      //turn on Tx_blank as well//
      delayMicroseconds(rise_delay);
      digitalWriteFast(3, LOW);
      detachInterrupt(digitalPinToInterrupt(interruptPin ));
      attachInterrupt(digitalPinToInterrupt(interruptPin ), fall, FALLING);
    }
    
    void fall() {
      //delay Rx_blank after falling edge//
      digitalWriteFast(4, HIGH);
      delayMicroseconds(fall_delay);
      digitalWriteFast(4, LOW);
      detachInterrupt(digitalPinToInterrupt(interruptPin ));
      attachInterrupt(digitalPinToInterrupt(interruptPin ), rise, RISING);
    }
    Here are the waveforms my oscilloscope sees.

    Click image for larger version. 

Name:	file.png 
Views:	23 
Size:	33.9 KB 
ID:	16107

    Notice on the right hand side the scope is showing the pulse width measurements.

    Here's how I tested the hardware.

    Click image for larger version. 

Name:	DSC_0358_web.jpg 
Views:	15 
Size:	151.1 KB 
ID:	16108

  6. #6
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    What I am having trouble with is that I start the interrupt on the rising edge of your top trace (read on pin2) and I want zero delay to the rising edge of your middle trace (write on pin 3). On both the Arduino nano and teensy LC this seems to be variable at about 3us. I'm hoping to get this delay to below 1us.

  7. #7
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,565
    Hm, I think you need a teensy 3.2:

    Click image for larger version. 

Name:	pic_18_2.png 
Views:	23 
Size:	16.9 KB 
ID:	16109

    550ns

  8. #8
    Senior Member
    Join Date
    Feb 2017
    Posts
    275
    I'd look into using one of the LC's TPMs. You'd need to use a combination of input capture and output match modes, switching between them at every interrupt as necessary.

    Use an output match channel as your delayed output (Tx_blank). Set it to fire a fixed delay past the captured timer value.

    Use direct write to the PORTSET and PORTCLEAR registers at the capture interrupt for the output that needs to change immediately with your trigger signal (Rx_blank).

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,920
    Agreed, user 1 us latency is easy on the much faster boards.

    You might be able to do better if you use attachInterruptVector() to have your function called directly, so you can avoid the overhead of attaxhInterrupt’s handler. But you’ll want to carefully choose 2 pins on different native port, so you can skip the work of checking which pin. You’ll also need to clear the port interrupt flag, but easy to just copy that from the attachInterrupt handler.

    Also use FASTRUN on your handler function, so it’s in single cycle RAM. Again, this helps most on the faster 3.X hardware which had dual 32 bit buses to memory, but may also help a bit on Teensy LC.

  10. #10
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    Thanks guys, I'll get a teensy 3.2 and get this working and then try out the other solutions later!

  11. #11
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    my teensy 3.2 arrived today and works beautifully. Thanks to all who helped me with this!
    Where do I find the document on all the teensy Arduino - style commands?

  12. #12
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    I've now been asked to add a new feature to this delay circuit. We would like to shape the output rise and falltimes to decrease the high frequency content of the waveform; it's possible we may be able to manage with one output. I could feed one of the digital outputs into a D to A and have a few rise points, but before I start on this I wanted to find out what problems I may run into; do you think this is possible on the Teensy 3.2 or would I need a faster Teensy? It's probably going to be something like maintaining the timing above and having a 1us rise and fall time.

  13. #13
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,381
    That is the moment to study the MK20DX256 Manual chapter 11, page 219, to look up how to modify drive strength and slew rate for individual GPIO pins...

  14. #14
    Junior Member
    Join Date
    Mar 2019
    Posts
    7

    modifiying slew rate on GPIO pins.

    Quote Originally Posted by Theremingenieur View Post
    That is the moment to study the MK20DX256 Manual chapter 11, page 219, to look up how to modify drive strength and slew rate for individual GPIO pins...
    Thank you, I will do so!

    Ed

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •