Teensy LC: Wrong action on Port D pins

Status
Not open for further replies.

ulihuber

New member
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
 
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.
 
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.

file.png

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