Interesting: Writing to UART_C2 before serial-init locks up

Status
Not open for further replies.

shawn

Well-known member
If UART_C2 is set before the corresponding serial port is initialized, despite the fact that the datasheet says it can be read or written at any time, seems to lock up the Teensy. Does anyone know why this may be? I can't seem to find any information about this in the datasheet. My guess is the UART clock isn't enabled.

Code:
void setup() {
  Serial.begin(115200);
  while (!Serial && millis() < 4000) {}

  Serial.println("1");
  // Serial3.begin(115200); <-- Uncomment to not lock up
  UART2_C2 &= ~UART_C2_ILIE;
  Serial.println("2");  // <-- This doesn't print

}

void loop() {
}

This was tried on a Teensy 3.2.
 
Last edited:
Basically, the registers of all system modules are only available when the module is enabled trough its clocking in the SIM. So, registers can be written or read at any time when these "exist". And they exist only if the module is activated. I guess that has to do with the power consumption management.
 
I can't seem to find mention of this fact in the chip guides. Do either of you know where this may be mentioned?
 
Look on page 160 of the MK20DX256 ref manual.

https://www.pjrc.com/teensy/K20P64M72SF1RM.pdf

clockgate.png
 
Respectfully, I must disagree. I can't just take this as a fact without either an errata or documentation. If it's not documented, it's a bug or needs an errata in the docs. But as I'm writing this, I see Paul's response...

IIRC, it's in the detailed description of the SIM module. But that's not important. Just take it as a fact...
 
Respectfully, I must disagree. Before you can use your vacuum cleaner, you have to plug its power cord into a wall plug. That's common sense even if not mentioned in the manual. :)
 
FWIW, this feature isn't unique to Teensy. Nearly all modern microcontrollers are designed this way, where as many peripherals as possible default to a low-power disable state. The small downside it a little more code is needed to turn them on. The huge upside is people seeking to achieve low power usage have a much easier time.

If you're used to old 8 bit chips like AVR, PIC, HC08 & 8051, where the chip boots up with pretty much everything active, this may seem strange. But it really is the norm now.
 
@Theremingenieur - I believe it's important to remember we get quite a lot of folks here with a ton of prior experience on very old embedded platforms.
 
Then again, this stuff is pretty clearly documented in the "fine" manual. ;)

@shawn - One strategy you can use to find these sorts of details involves looking at the existing code for what registers it initializes. The names used in serial1.c and other Teensyduino files are exactly the same as they appear in the manual (no extra layers of naming as NXP's complex code tends to use) so you can just copy them right into the search box on whatever program you use to read the manual PDF file. For example, searching for "SIM_SCGC4" which Frank mentioned in msg #2, and you would see in the initialization code in serial1.c, goes right to page 252. Going from "System Clock Gating Control Register 4" to chapter 5 "Clock Distribution" isn't as automatic. But hopefully you can see a path here that doesn't involve insinuating on a forum that these features are undocumented or hidden?
 
@Theremingenieur I hear your point, however, most vacuum cleaner documentation (and most other basic home appliance documentation) actually document the fact that you need to plug it in. That's in addition to a mention of plug safety.

I'm sorry, but "setting a bit on this register will lock up the microprocessor and not just be ignored" is not common sense.

Respectfully, I must disagree. Before you can use your vacuum cleaner, you have to plug its power cord into a wall plug. That's common sense even if not mentioned in the manual. :)
 
Thanks for your response, Paul. For the record, I never insinuated that this wasn't documented or hidden. I specifically said: "I can't seem to find any information about this in the datasheet. My guess is the UART clock isn't enabled." That doesn't mean it's not there, just that I couldn't find it. I must have missed that sentence in the manual, but I see it now; thanks for pointing it out.

My reference to being undocumented or a bug was specifically a response to @Theremingenieur saying "Just take it as a fact.". I don't believe in just accepting microprocessor behaviour, especially if something turns out to be undocumented, which was @Theremingenieur's implication, not mine. I didn't misrepresent or insinuate anything.

Sometimes, and I'm sure we all can agree on this point, we're so deep into the manuals and documentation that finding that one sentence is difficult and it's easy to miss. In this case, I missed it. The information is very dense, and I'm also sure we've all been there, where you need another set of eyeballs to see what's in front of your face.

And that's why I asked on this forum, because I was sure that someone may have seen it.

Then again, this stuff is pretty clearly documented in the "fine" manual. ;)

@shawn - One strategy you can use to find these sorts of details involves looking at the existing code for what registers it initializes. The names used in serial1.c and other Teensyduino files are exactly the same as they appear in the manual (no extra layers of naming as NXP's complex code tends to use) so you can just copy them right into the search box on whatever program you use to read the manual PDF file. For example, searching for "SIM_SCGC4" which Frank mentioned in msg #2, and you would see in the initialization code in serial1.c, goes right to page 252. Going from "System Clock Gating Control Register 4" to chapter 5 "Clock Distribution" isn't as automatic. But hopefully you can see a path here that doesn't involve insinuating on a forum that these features are undocumented or hidden?
 
sometimes if the gas pedal is to be expected to drive a car, doesn’t mean the ignition is running. Loss of expectations :)
 
but "setting a bit on this register will lock up the microprocessor and not just be ignored" is not common sense.

I'm going to guess you've not done much with ARM chips until now?

On most older chips, if you access something that's turned off, or you try to read from a memory location that doesn't exist, you get a random result. Nothing out of the ordinary happens, just random data. That's the way things were, and still are if you use old tech.

With ARM (and maybe other modern architectures), the bus system inside the chip reports an error which generates a memory fault interrupt / exception. The default exception routines are infinite loops which try to flush any unsent serial & USB data, but otherwise do nothing.

What is and isn't "common sense" depends on your experience. With these modern parts, nearly all peripherals default to a low power disabled state, and nearly all bus access to memory mapped stuff is checked by hardware and generates an interrupt / exception if you try to read or write anything that isn't accessible. This may not be common sense if you've not worked with these modern parts before... but it really is common sense to those who've been using them for several years.
 
...
With ARM (and maybe other modern architectures), the bus system inside the chip reports an error which generates a memory fault interrupt / exception.
...

Wondering / guessing this is part of chip security in the ARM world? These MCU's can do privilege protection, built to support an RTOS. Having the chip not fault when doing unauthorized/initialized hardware access would allow working out ways to abuse the system.
 
That's right. My TeensyDMX project is my first major foray into some of the direct-access chip stuff. It was only this year that I started diving more deeply into it. Thanks for the explanation.

I'm going to guess you've not done much with ARM chips until now?

On most older chips, if you access something that's turned off, or you try to read from a memory location that doesn't exist, you get a random result. Nothing out of the ordinary happens, just random data. That's the way things were, and still are if you use old tech.

With ARM (and maybe other modern architectures), the bus system inside the chip reports an error which generates a memory fault interrupt / exception. The default exception routines are infinite loops which try to flush any unsent serial & USB data, but otherwise do nothing.

What is and isn't "common sense" depends on your experience. With these modern parts, nearly all peripherals default to a low power disabled state, and nearly all bus access to memory mapped stuff is checked by hardware and generates an interrupt / exception if you try to read or write anything that isn't accessible. This may not be common sense if you've not worked with these modern parts before... but it really is common sense to those who've been using them for several years.
 
Status
Not open for further replies.
Back
Top