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

Thread: Teensy LC: Wrong action on Port D pins

  1. #1
    Junior Member
    Join Date
    Nov 2019
    Posts
    3

    Teensy LC: Wrong action on Port D pins

    Hi,

    I am new to Teensy, doing first tests and can't understand a behavior of the board.
    I took the 'Blink Example" and modified to see simultanious action on all port D0..D7 pins (2,14,7,8,6,20,21,5).
    Code:
    // Simple LED blink
    
    const int led = LED_BUILTIN;
    
    void setup() {
      pinMode(led, OUTPUT);
      DDRD = 0xff;
    }
    
    void loop() {
      PORTD = 0xff;
      digitalWrite(led, HIGH);
      delay(5);
      PORTD = 0x00;
      digitalWrite(led, LOW);
      delay(5);
    }
    But this does not work out the way I expected:
    I see a 100kHz with sharp edges on board's pins 1,4,7 (and 13/LED). Same signal with visibly rounded falling edges on board's pins 0,2,3. Constant high level on 5 and 6 and low level on 8,20,21.

    Do I have a broken Teensy or a misunderstandig of the port mapping?

    Thanks
    Uli

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    578
    The TeensyLC has an ARM controller not an AVR. So, accessing AVR registers (PORTD ...) doesn't make much sense. However, for some (portability?) reason there is emulation code in avr_emulation.h which simulates some AVR port accesses by issuing series of DigitalWriteFast() . Never tried it, and I don't know if this is supposed to work at all.

    You can as well do the digitalWriteFast() yourself which might be less confusing. If you really need to access a whole port instead of single pins you should use the ARM specific registers instead.

    Hope that helps.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,795
    On Teensy 3.x and LC, the old AVR port registers are software emulated (as if Arduino Uno). That allows most very old Arduino code to run without modification.

    To get maximum speed software toggling on the LED pin, use this:

    Code:
    void setup() {
      pinMode(13, OUTPUT);
    }
    
    void loop() {
      while (1) {
        digitalWriteFast(13, HIGH);
        digitalWriteFast(13, LOW);
        digitalWriteFast(13, HIGH);
        digitalWriteFast(13, LOW);
        digitalWriteFast(13, HIGH);
        digitalWriteFast(13, LOW);
        digitalWriteFast(13, HIGH);
        digitalWriteFast(13, LOW);
        digitalWriteFast(13, HIGH);
        digitalWriteFast(13, LOW);
        digitalWriteFast(13, HIGH);
        digitalWriteFast(13, LOW);
      }
    }
    Looping overhead is a major factor in the speed you can get. Here's the waveform Teensy LC creates on pin 13 when running this code.

    Click image for larger version. 

Name:	file.png 
Views:	1 
Size:	30.0 KB 
ID:	18154

    Hopefully you can see those digitalWriteFast() really do execute in 1 cycle (of 48 MHz), giving a stream of pulses at 24 MHz as the code runs without looping. Then the gaps are from the while() loop. Returning from loop() which runs stuff like serial event checking takes even longer.

  4. #4
    Junior Member
    Join Date
    Nov 2019
    Posts
    3
    Ok, I understand that my old fashioned controller knowledge needs an update...and of course I can use digitalWriteFast in own programs I'll write. Thanks for the hint.

    In fact, my test resulted from a not working project I pulled from GitHub: https://github.com/Tuet/XY2_100
    It compiled OK but gives also no output on my Teensy LC and due to the complicated DMA it is really hard to debug. My intention was to first look after basic functionality before digging deeper in the code.

    Maybe someone can have a look at it and give some advice.

    Thanks
    Uli

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,083
    Quote Originally Posted by ulihuber View Post
    Ok, I understand that my old fashioned controller knowledge needs an update...and of course I can use digitalWriteFast in own programs I'll write. Thanks for the hint.

    In fact, my test resulted from a not working project I pulled from GitHub: https://github.com/Tuet/XY2_100
    It compiled OK but gives also no output on my Teensy LC and due to the complicated DMA it is really hard to debug. My intention was to first look after basic functionality before digging deeper in the code.

    Maybe someone can have a look at it and give some advice.

    Thanks
    Uli
    Github update 9 months ago - maybe an Issue there will get resolved by the author? Might just be a IDE/Toolchain update or minor untested T_LC case.

  6. #6
    Junior Member
    Join Date
    Nov 2019
    Posts
    3
    Quote Originally Posted by defragster View Post
    Github update 9 months ago - maybe an Issue there will get resolved by the author? Might just be a IDE/Toolchain update or minor untested T_LC case.
    I was unable to find a contact but bought a Teensy 3.2 which works nicely. I guess the code was orginally written for the 3.2 and the port to LC has a bug within the DMA initialisation. I am not going to do a search for this bug on the LC but rather invest time (when possible) in a port to 4.0

    Thanks
    Uli

Posting Permissions

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