DigitalWriteFast on a single pin is setting multiple pins on Teensy 4.1.

Cormallen

New member
I'm trying to turn some pins on and off using DigitalWriteFast.

This is something I do with other pins in the project, and have never had a problem with it. Now I've started writing the code that deals with four pins that I hadn't been using before. The code looks something like this.

Code:
#define GATE_OUT_1 39
#define GATE_OUT_2 38
#define GATE_OUT_3 37
#define GATE_OUT_4 40

pinMode(GATE_OUT_1, OUTPUT);
pinMode(GATE_OUT_2, OUTPUT);
pinMode(GATE_OUT_3, OUTPUT);
pinMode(GATE_OUT_4, OUTPUT);

digitalWriteFast(GATE_OUT_4, HIGH); // Example - could be any of them.

Which looks pretty straightforwards to me! The problem is that setting/clearing any of those four pins ALSO sets/clears pins GATE_OUT_1 & GATE_OUT_2.

I've dug down into the code for digitalWriteOut, and have made sure it's doing what I think it should.

I notice that one of the the Teensy SPI hardware units use pins 38 and 39. I am using that unit, and was wondering if that was somehow interfering with things, though I use a different CS pin, and I don't use the MISO at all. But do I have do some to explicitly turn it off?

Or is there something else going on?

Many thanks!
 
I don't see that issue: Here is a complete sketch:
Code:
#define GATE_OUT_1 39
#define GATE_OUT_2 38
#define GATE_OUT_3 37
#define GATE_OUT_4 40

void setup() {
  pinMode(GATE_OUT_1, OUTPUT);
  pinMode(GATE_OUT_2, OUTPUT);
  pinMode(GATE_OUT_3, OUTPUT);
  pinMode(GATE_OUT_4, OUTPUT);
}

void loop() {
  digitalWriteFast(GATE_OUT_1, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_1, LOW);
  delay(5);
  digitalWriteFast(GATE_OUT_2, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_2, LOW);
  delay(5);
  digitalWriteFast(GATE_OUT_3, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_3, LOW);
  delay(5);
  digitalWriteFast(GATE_OUT_4, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_4, LOW);
  delay(5);
  
}

Screenshot.png

Edit, maybe check that you don't have some form of short.
 
I don't see that issue: Here is a complete sketch:
Edit, maybe check that you don't have some form of short.

Yes, I know that works. That was sort of my point!

The hardware is all fine - no shorts, and I'm not doing anything that I haven't tested before; I'm pretty sure that this is a firmware issue. Things work perfectly well on another 20 or output pins. It's only these four that are causing me issues. Hence the question about whether me using that SPI unit could interfere with things.

I can try to post a complete example that fails, but it's going to take me a lot of work; the full project is something like 15,000 lines of C, plus a bunch of third-party libraries. Cutting that back to a small example that shows the failure is going to be non-trivial :-(

Thanks.
 
Note: I posted the code I tried, plus output, that at least in the simple case the hardware and digitalWriteFast is working

And potentially if you have a logic analyzer or Oscilloscope, you maybe could try to see if you have the same results.

So I suspect probably some form of electrical or software connection between your pins.

Looking at the pins involved:
Screenshot.png

37: is a chip select pin on the SPI object - It would only be used by SPI, if SPI.setCS(37); and again pinMode(37, OUTPUT); would overwrite that.
38: is a chip select pin on the SPI1 object . again only...
39: is an alternate MISO pin for SPI1 object. SPI1.setMISO(39). And again pinMode would overwrite that.
40: is not part of any SPI object.

You might try some simple tests to see if there is an electrical issue: For example if I expand the sketch posted before:
Code:
#define GATE_OUT_1 39
#define GATE_OUT_2 38
#define GATE_OUT_3 37
#define GATE_OUT_4 40

void setup() {
  while (!Serial && millis() < 5000) ; 
  pinMode(GATE_OUT_1, OUTPUT);
  pinMode(GATE_OUT_2, OUTPUT);
  pinMode(GATE_OUT_3, OUTPUT);
  pinMode(GATE_OUT_4, OUTPUT);
  
  for (uint8_t i = 37; i < 41; i++) {
    Serial.printf("pin: %u CTRL:%x CFG:%x\n", i,
      *(portControlRegister(i)), *(portConfigRegister(i)));
  }
  
  // Simple test to see if connected?
  pinMode(GATE_OUT_1, INPUT_PULLDOWN);
  pinMode(GATE_OUT_2, INPUT_PULLDOWN);
  delay(1);
  digitalWriteFast(GATE_OUT_4, HIGH);
  Serial.printf("%u HIGH %d %d\n", GATE_OUT_4, digitalReadFast(GATE_OUT_1), digitalReadFast(GATE_OUT_2));

  pinMode(GATE_OUT_1, INPUT_PULLUP);
  pinMode(GATE_OUT_2, INPUT_PULLUP);
  delay(1);
  digitalWriteFast(GATE_OUT_4, LOW);
  Serial.printf("%u LOW %d %d\n", GATE_OUT_4, digitalReadFast(GATE_OUT_1), digitalReadFast(GATE_OUT_2));
  
  pinMode(GATE_OUT_1, OUTPUT);
  pinMode(GATE_OUT_2, OUTPUT);
}

void loop() {
  digitalWriteFast(GATE_OUT_1, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_1, LOW);
  delay(5);
  digitalWriteFast(GATE_OUT_2, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_2, LOW);
  delay(5);
  digitalWriteFast(GATE_OUT_3, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_3, LOW);
  delay(5);
  digitalWriteFast(GATE_OUT_4, HIGH);
  delay(5);
  digitalWriteFast(GATE_OUT_4, LOW);
  delay(5);
  
}

My output on the T4.1 with just inputs to Logic Analyzer, I see:
Code:
pin: 37 CTRL:38 CFG:15
pin: 38 CTRL:38 CFG:15
pin: 39 CTRL:38 CFG:15
pin: 40 CTRL:38 CFG:15
40 HIGH 0 0
40 LOW 1 1

The first 4 lines show the pins are in GPIO mode: hex 15, the mode is 5 which is GPIO.

The second part shows if the pins are somehow connected.
That is if I change the two pins you say change to INPUT_PULLDOWN and set one of the others to HIGH, if they are not connected the pins should stay low.
Likewise if I set the PULLUP and then set the other IO pin to LOW, I would expect the pins to stay high.
 
It turns out it was a damaged Teensy; I probably buggered it up a couple of years ago when breadboarding something.

I switched it out for a new one, and all the problems disappeared.

Many, many thanks for your time.
 
Back
Top