Voltage Appearing on LED_BUILTIN pin during startup, Teensy 3.2

grinch

Well-known member
Hi, I am working on a project using a Teensy 3.2 alongside a custom motherboard PCB. My project is working well except for the fact that I am seeing a voltage at the LED_BUILTIN pin when I give power to my board. This is despite the fact that I explicitly write this low as the very first action in setup(). Basically, it seems like the Teensy takes a while after getting power to actually start running any code, and during this interval the LED_BUILTIN pin (pin 13) is high.

I am using this setup to control some high voltage transformers, and having one of them stuck randomly on for half a second at startup will actually create some really big problems in my application. As is right now, I have to plug in that particular channel after the board has received power and gone through its startup sequence.

Is there anything I can do to fix this? Does this seem like a software thing or a hardware thing? Can't find anything on the Teensy schematic that would cause this, it looks like the LED_BUILTIN pin just has a resistor and LED to ground.

Please advise.

Here is the code I am running in setup:

Code:
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
....

Here is the schematic for my project's board:
https://github.com/hhaudio/HiveController/blob/border/WaspHive_Schem.pdf
 
Grinch:
I far as I can tell the HC245's input on pin 18 is floating (tri-state), as I believe that the Teensy pins are in tri-state mode until you specifically put them into input or output mode.

You have a power on reset problem, the HC245's input is floating which usually means the output on pin 1 is high. You will probably have to deal with this in hardware to disable the output of the HC245's output pins and pull them to ground, or some such thing.

Regards
Ed
 
If your only problem is with the LED pin, then the likely culprit is in the startup code. I took a quick look to see if I could spot anything but didn't.

There is a hook to allow you to run code early, well before the code to ramp up the clock system and USB with their long delays. The catch is that it happens before clocks are enabled for the GPIO. So writes to those registers will fail horribly unless you enable the clocks yourself.

HC245's may not be the best choice since CMOS dislikes floating inputs and should probably have pull down resistors on their inputs.. I can think of better choices but they work better if the output is active low.
 
Grinch:
I far as I can tell the HC245's input on pin 18 is floating (tri-state), as I believe that the Teensy pins are in tri-state mode until you specifically put them into input or output mode.

You have a power on reset problem, the HC245's input is floating which usually means the output on pin 1 is high. You will probably have to deal with this in hardware to disable the output of the HC245's output pins and pull them to ground, or some such thing.

Regards
Ed

If this is the case, why is it that only the LED pin sticks high when power is applied to the board? This pin actually has a pull-down in the form of the resistor and LED to ground, and so should be pulled low by default. Is there anything that you can think of that would account for the one pin that actually has a pulldown being the pin to stick high?
 
Interesting do you know where I can find an example for enabling these hooks? Seems like if I can startup up the GPIO clocks and write everything low as the very first thing that the Teensy does upon receiving power this should resolve my issue.

Is this what I should be looking at? Defining GPIO registers as OUTPUT, LOW in this startup file mk20dx128.c?

https://forum.pjrc.com/threads/44692-Optimizing-Teensy-3-2-Startup
 
So I'm looking at this code in mk20dx128.c:

Code:
static void startup_default_early_hook(void) {
#if defined(KINETISK)
	WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;
#elif defined(KINETISL)
	SIM_COPC = 0;  // disable the watchdog
#endif
}
static void startup_default_late_hook(void) {}
void startup_early_hook(void)		__attribute__ ((weak, alias("startup_default_early_hook")));
void startup_late_hook(void)		__attribute__ ((weak, alias("startup_default_late_hook")));

This seems to imply that I can run code immediately on reset simply by defining a startup_early_hook() function and filling it with the necessary code. Is that correct?

Looking at the startup code for initializing the GPIO clocks, I see that it runs right after the startup_early_hook() function is called in Reset_Handler():

Code:
	startup_early_hook();

	// enable clocks to always-used peripherals
#if defined(__MK20DX128__)
	SIM_SCGC5 = 0x00043F82;		// clocks active to all GPIO
	SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
#elif defined(__MK20DX256__)
	SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2;
	SIM_SCGC5 = 0x00043F82;		// clocks active to all GPIO
	SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
	SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2 | SIM_SCGC3_FTM3;
	SIM_SCGC5 = 0x00043F82;		// clocks active to all GPIO
	SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
	//PORTC_PCR5 = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE;
	//GPIOC_PDDR |= (1<<5);
	//GPIOC_PSOR = (1<<5);
	//while (1);
#elif defined(__MKL26Z64__)
	SIM_SCGC4 = SIM_SCGC4_USBOTG | 0xF0000030;
	SIM_SCGC5 = 0x00003F82;		// clocks active to all GPIO
	SIM_SCGC6 = SIM_SCGC6_ADC0 | SIM_SCGC6_TPM0 | SIM_SCGC6_TPM1 | SIM_SCGC6_TPM2 | SIM_SCGC6_FTFL;
#endif

Can I simply copy this code into the startup_early_hook() function to have GPIO clocks active immediately? Is there any danger in having this clock setup run twice? I would much rather avoid editing library code since this can mess with other projects I'm working on. Also, is it sufficient to activate the GPIO clocks then immediately run something like this to have all the GPIOs set up and written low? :

Code:
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
 
If this is the case, why is it that only the LED pin sticks high when power is applied to the board? This pin actually has a pull-down in the form of the resistor and LED to ground, and so should be pulled low by default. Is there anything that you can think of that would account for the one pin that actually has a pulldown being the pin to stick high?

grinch:
The resistor and LED to ground is not a pull-down. The IV curve of a LED is not the same as an ordinary diode. I am not sure which type of LED Paul used but the forward on voltage for a red LED is somewhere between 1 and 2 volts. So until the voltage at the LED's anode rises above the forward conduction voltage its is effectively not there.

The CMOS input of the HC245 will not be in a stable state until the input is pulled high or low from an external source, I have seen them oscillate when left floating.

Does the Teensy's LED actually glow during the startup period you mentioned? If so something in the Teensy's startup code is doing it, or there is a short somewhere in that node of your board.

I would yank the Teensy out of the circuit and put an O'scope or fast DVM on the pin to see if the source of the logic high is the Teensy or something else in your circuit board, like perhaps a solder bridge or some other type of short. These types of problems can be difficult to pin down sometimes.

I have used Teensy 3.2's since they first came out and have not seen anything like this, but as UhChem says using logic circuitry that is low active is always a better idea especially during the start-up of the board with all of its complicated circuitry. I have always used this technique in all my circuits for the last 50+ years.

Regards,
Ed
 
Back
Top