The only program that runs is Blinky

Status
Not open for further replies.

easyBob

Member
Hey everyone, I'm new here, and also new to the Teensy 3.1, but not uC's.

Anywho, it seems that the only program that will run on this thing is the Blinky program. Any time I try to set up anything else (PWM/UART to start), the program fails.

Here's a simple example:

Code:
int  main(void) {
	// set up blinky
	PORTC_PCR5 = PORT_PCR_MUX(0x1); // LED is on PC5 (pin 13), config as GPIO (alt = 1)
	GPIOC_PDDR = (1<<5);			// make this an output pin

	// system clock gating control register (enable FTM1 clock)
	SIM_SCGC6 |= (1 << 26);

	// set up PWM (FTM1_CH0) alt3 [digital pin 3 on teensy 3.1]
	PORTA_PCR12 = PORT_PCR_MUX(0x3);
	
        /*
        
        Fails here, always

        */
        // disable write protect (write protect seems useless to me, but whatever)
	FTM1_MODE |= FTM_MODE_WPDIS_MASK << FTM_MODE_WPDIS_SHIFT;
	
        ....
        ....
}

And it doesn't matter what I try. Even trying to read the FTM1_MODE register causes failure. I'm very honestly upset with this uC, and it's documentation (they should have just called it the Figure it Out Yourself Sheet, Because We Aren't Telling, And BTW, This Document Will Make Your Head Spin, So Enjoy!)

Thanks for any hints/tips,
-Chris
 
Last edited:
For just getting started, I'd highly recommend you use the Arduino IDE. All this stuff "just works". All the supporting code is visible in hardware/teensy/cores/teensy3.

If you're trying to write code from scratch like this, you're responsible for setting up all the hardware. Again, look in hardware/teensy/cores/teensy3 for known good examples.

Almost everything in the chip is disabled by default, even the I/O ports. They make disabled the default that for low power, so you have to turn things on before you access them. Any attempt to access any register, even merely reading a register from a disabled peripheral, causes a hard fault.

The easy way is using Arduino. Really, all this stuff works so very simply and easily.
 
Adding to Paul's statement... Coming from an AVR or some such, often one has to work at the I/O port level.
With Teensy 2, 3, the libraries (Teensyduino) are the focus. Almost never do you have to do low level I/O.
UART I/O is done with Serial() or Serial1() or Serial2() etc. These are interrupt driven, buffered.
GPIO bits are done with pinMode() and digitalWrite(), digitalRead()

It's like flying at 30K ft. instead of bare metal micro programming on the flight deck.
 
I understand that using Arduino is the fastest and simplest solution. I've used .NETMF before and it's just as easy and fast to setup and go (albeit slow as b*lls).

But still, I like to know the lower level stuff. I believe that by understanding it, I can make the best out of the chip I'm using. For example, I have a Gadgeteer Spider I use for high level hardware abstraction (controlling touch screen, reading SD Cards, I2C, etc), but the PWM for it was crap. It took maybe 20 minutes of fiddling around with low level access (RPL elf files) to get the PWM to ramp smoothly up and down (testing stepper motor drivers) without having to deal with the .NETMF Gadgeteer PWM restarting the PWM every time. The LPC24xxx chip it runs on was so easy to manipulate at the low level.

I'll look into the Arduino files though, see what they do. Maybe I'm just stuck on ARM7. Thanks though.

-Chris
 
I understand that using Arduino is the fastest and simplest solution. I've used .NETMF before and it's just as easy and fast to setup and go (albeit slow as b*lls).

I believe you'll find using Teensy 3.1 through Arduino still gives you very good speed.

But still, I like to know the lower level stuff.

Well, you certainly can dig into the low level stuff. Freescale's reference manual could be better (flipping between chapter 3 for chip-specific details and other chapter for generic peripheral docs is a pain), but really, it's just not realistic to believe learning the very low-level details for any new chip will be easy.

Pretty much all modern microcontrollers are now using this approach, where most stuff in the chip is disable by default. ARM processors also have bus fault detection. If you're used to old 8 bit chip where everything is enabled by default and attempts to access things that don't exist just return garbage, well, that's just not how modern 32 bit parts work.

I believe that by understanding it, I can make the best out of the chip I'm using.

You might be able to do better than some of the Arduino support code. The SPI library is one place where going to the native registers gives a pretty tremendous increase. Several of the TFT libraries and the SD library already have native SPI code. Some stuff, like digitalWrite() is burdended with emulating quicks of Arduino's AVR registers, but you can use digitalWriteFast() to get the ease of Arduino-like APIs while compiling to a single bus cycle.

Most of the support code, like the USB stack, contains quite a bit of fairly complex code that really leverages the sophisticated hardware to good effect. The USB port uses DMA transfers and a flexible pool of shared buffers for very efficient data movement, even with simple Arduino programs that use delay(). Likewise, the serial code uses interrupts, buffers, and the FIFO on Serial1 to very good effect.

I'll look into the Arduino files though, see what they do.

A far more approachable way, which happens to be the way most people also approach 8 bit AVR, is to use the Arduino libraries and occasionally access only limited parts of the hardware directly for the cases where higher performance is needed.

Maybe I'm just stuck on ARM7. Thanks though.

I'm pretty sure you'll find most of Teensy 3.x support code is MUCH more efficient that the micro .net platform!

The ARM Cortex-M4 is also *much* faster than ARM7TDMI, especially running from slow external memory accessed through only a 16 bit bus. Teensy 3.1 runs entirely from internal memory with two 32 bit buses from the CPU core to a switched bus matrix interconnecting all the fast on-chip memory, and 2 dedicated buses to the RAM.

Even if both have a 72 MHz clock, the ARM7TDMI is a much slower architecture, and it's hobbled by a slow 16 bit bus on that board, even if the software were highly efficient. Freescale's Kinetis chip has much, much better performance than those old Atmel ARM7TDMI parts!
 
Last edited:
I did a lot of bare metal coding for ARM7 (NXP LPC2xxx) for my job. But now, with Teensyduino, most bare metal coding isn't needed.
 
I agree that this chip is better than the arm7, but it is def. more of a challenge.

Which reminds me, I have PWM going....An LED is blinking, it has blunk, and it's with PWM....finally!


Excuse me while I now go cry in the shower :S

-Chris
 
In practice, a lot of custom "bare metal" code ends up being very simplistic polled I/O, because developing a sophisticated driver with interrupts, buffering, and complex code to fully leverage the complex hardware features requires a lot of programming time and debugging effort.

Freescale writes in chapter 12:

The examples included here poll UART status flags to determine when receive data is
available or when transmit data can be written into the FIFO. This approach is the most
CPU intensive, but it is often the most practical approach when handling small messages.
As message sizes increase it might be useful to use interrupts or the DMA to decrease the
CPU loading. However, the overhead required to set up the interrupts or DMA should be
taken into account. If the additional overhead outweighs the reduction in CPU loading,
then polling is the best approach.

Their example doesn't even use the FIFO, despite what this says, and unbuffered I/O is rarely "the most practical approach".

If you're building a complex project which does anything substantial code-wise and uses higher baud rates, odds are not good you'll be able to call uart_getchar_present() fast enough to avoid missing incoming bytes.

Of course, being a bare metal project, you'd write UART driver code specially matched to your specific needs. Maybe you'd go to the trouble to use interrupts and buffering (or copy Teensyduino's code)?
 
That's all very true.

Most of my projects that require uart basically come down to sending command chars so the uC/PC know what to expect next. Simple.

I'm going to try and not pull my hair out next trying to figure out I2C....I have yet to see any code examples on this, so this one might just come down to looking through more Arduino code (which feels like cheating though :( ) In the end, I might just go and set up Arduino on the Teensy, just for ease of use, even though it's still fun to stress over figuring out the bare metal stuff :).

-Chris
 
I'm going to try and not pull my hair out next trying to figure out I2C....I have yet to see any code examples on this,

You could look at the Wire library! Just run the Teensyduino installer, then look in libraries/Wire. Easy! ;)

Or you could look at Nox771's i2c_t3 library.

http://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3


so this one might just come down to looking through more Arduino code (which feels like cheating though :( ) In the end, I might just go and set up Arduino on the Teensy, just for ease of use, even though it's still fun to stress over figuring out the bare metal stuff :).

Why not have your cake and eat it too?!

Install Arduino+Teensyduino and use all the easy stuff that already exists.

Then dig into the insanely complex details of a specific peripheral you really want to use. For example, the FTM0 timer has 8 channels that support all sorts of advanced PWM and other features which currently have no library code. The CMT is used by the IRremote library, but only in a very simple way. It's capable of so much more. SPI slave mode is another place where very little good code exists. Special USB types, especially those requiring isync transfer types, aren't supported (yet).
 
... so this one might just come down to looking through more Arduino code (which feels like cheating though :( ) In the end, I might just go and set up Arduino on the Teensy, just for ease of use, even though it's still fun to stress over figuring out the bare metal stuff :).

-Chris
Like running through hot coals is fun!!

If you like bare metal learning/coding... contribute to libraries!
 
Status
Not open for further replies.
Back
Top