Teensy 4.0 how to get a serial connection to pc (theoretical)

Status
Not open for further replies.

Lockna

Member
So, as the title says I'm wondering how I can get a serial connection to the pc via usb. I don't have any code written yet. I want to understand it in theory.

I have a Teensy 4.0 development board. I want to program it using the Rust programming language. So I cannot use their implementation of the Arduino library for it (I wouldn't use it either if I would use C)

My goal is to write some bare-metal drivers for it, maybe a HAL (afaik a HAL is comparable like a library, I write the Hardware Access etc. and I provide fancy functions to use he board)

I have to get a serial connection to the PC. The best would be via USB, but how do I get startet to it? My first thought was to search the MMIO registers for the UART. But I have no clue how to get the UART to the USB Port of the board.

Would be nice, if someone could explain this to me
 
Sorry I am not sure what you are really asking?

If you wish to go total bare metal, you would need to start by reading the Hardware Reference Manual and the like for the processor, which you can find up on the PJRC site.

Sorry for the most part I know more or less nothing about RUST, so not sure if you have IDES or the like and if they have versions that will compile for IMXT1060 like processor or not. Nor what pieces they provide and what pieces they expect you to fill in.

As for HAL (Hardware Abstraction Layer), they can be as simple as a library that provides some fixed APIs/Objects, but still allow the code calling the HAL APIs to still touch the underlying stuff. Or they could have protection schemes, like layers ...

Serial connection to PC - The simplest is to go through a Hardware Serial port. In fact for a long time during the T4 beta cycle we did not have USB serial working at all, and we did all of our debugging using a Hardware Serial port (Serial4 if I remember correctly)


The Hardware Serial ports are reasonably easy to get the basics working. BUT this is only after you get many other initial things working. Maybe things like initialize all of the timers,
memory regions, interrupt vectors, GPIO...

Then it is reasonably easy to setup a GPIO to work real basic. Then you can use your favorite USB to serial adapter to have it actually talk to the PC... (Could be another teen).

As to get USB Serial to work. LOTS of work. You will need a very good understanding of USB.

Personally I like to cheat, and use the underlying Arduino code that Paul (and many others of us) have put a lot of time into. Any you have the ability to build it outside of Arduino using different IDES, which may or many not use the Arduino build system, they may also use make...

So again I am not sure of your full goals, but if it were me, I would see what RUST needed from the system and then work for building a simple "HAL" that simply called through using the Teensyduino core sources...

Again sorry I am not sure if this helped or not.

Good luck, will be interesting to see what you come up with.
 
Thanks for answering.
So, I already found the datasheet of the cpu and I'm reading occassionally in it (is this valid english?^^)

I prefer to write the code in a editor like VSCode or Vim and compile and flash it via cli. Rustc supports arm-cortex-m7 as a target. For flashing I'm gonna use the teensy-cli-loader.

Yeah, I'll start with a simple HAL

So, when I use a hardware serial port, how do I get the signal onto the PC? ^^ I mean when I send a message, how can I receive it with the pc?

Hmm, yeah I'll think about it

I have to say, I don't really get it how the teensy works with arduino stuff^^
Afaik, they have rewritten the complete arduino library.
Teensyduino is a Plugin for the Arduino IDE.

As I said before, thanks for answering.
It actually helped me already a lot^^
 
I prefer to write the code in a editor like VSCode or Vim and compile and flash it via cli.

The Arduino IDE has an "external editor" option in File > Preferences. If you turn that on, Arduino's editor is disabled so you can edit the files with vim or vscode or anything else. It automatically detects when you've saved changes. Of course you can still use Verify, Upload and the Serial Monitor.

Even if you later switch to the command line loader, this way is the easiest to get started and can let you focus on understanding the hardware and existing code before you also dive into customizing the tools and build process. Life is much easier when you don't try to take on too many unfamiliar things all at once!


I have to get a serial connection to the PC. The best would be via USB, but how do I get startet to it? My first thought was to search the MMIO registers for the UART. But I have no clue how to get the UART to the USB Port of the board.

Again, before you deep dive into the code, at least do something like this in Arduino and watch it print to the serial monitor:

Code:
void setup() {
}
void loop() {
  Serial.println("Hello World");
  delay(500);
}

Even if your end goal it to not use Arduino, at the very least you can copy this into Arduino, select Teensy in Tools > Boards, and upload it to your Teensy. Then select Tools > Ports and open the serial monitor. Having a known good starting point makes all of this so much easier than trying to craft code from scratch.

The code which actually implements these functions is in {Arduino}/hardware/teensy/avr/cores/teensy4. It's also on github. If you read through the code, you'll find the Print class ultimately calls usb_serial_write() in usb_serial.c with bytes you're transmitting. Ultimately it's just copying bytes into a transmit buffer and then writing to the transfer descriptor structures in memory to tell the USB hardware what to do.

To understand how the hardware works, you'll need the IMXRT1060 reference manual. It's available here:

https://www.pjrc.com/teensy/datasheets.html

The USB controller uses DMA to read that struct from memory, and the read the data from memory too. If you're used to programming simple peripherals like UARTs where you write to registers, this concept of writing to a chunk of memory may seem strange. You do also write to registers, but mainly just to "prime" the endpoint to start reading from memory. There's also a register to tell the hardware where your top-level data structure is placed in memory. But pretty much everything else is done though the data structures in memory rather than hardware registers. The USB hardware is pretty regularly access the memory to do its work.

That transfer descriptor data format is documented starting on page 2348 with Table 42-61 showing the various fields on page 2349, and which bits the hardware will modify as it works on transmitting the data. You can also find the other in-memory data structures documented on nearby pages.

Of course this is just part of the complete USB code. There's also code in usb.c which initializes the hardware and responds to events and answers the many USB control transfer messages which are required by the USB protocol, using the data defined in usb_desc.c and usb_desc.h (which is how your PC knows it's implementing USB serial).

There's quite a lot of code in there to read, and realistically to make sense of most of the USB stuff you'll probably need to read at least chapters 4, 5, 8 and 9 of the USB spec. Here's a direct link to just the PDF, which you can of course get from www.usb.org, but it takes a little digging to find it.

https://www.pjrc.com/teensy/beta/usb20.pdf

You can edit any of these files and the Arduino IDE will automatically recompile them. As a quick sanity check, I usually add a syntax error and click Verify, just to make sure I'm editing the right copy that Arduino really is compiling before each upload.

If you really want to start your own HAL completely from scratch, that is theoretically possible. It would be pretty hypocritical of me to say not to do so, since I (and some contributions from KurtE and others) wrote all that core library code from scratch. Nearly 2 years of intense effort was needed to get everything in Arduino working well on Teensy 4. If you're willing to take on such a lengthy project, you certainly can. But you can save yourself a lot of time by leveraging the low-level code which already works.
 
Hey, thank you!

Yeah, I'm gonna try the Teensyduino and then go to cli. But when I go to Rust with it, then I have to use a cli flashing tool.

So, for understanding, you've implemented the Arduino Core Library yourself (and other contributers). You can use it with a Teensy, but isn't the Arduino IDE compiling for AVR? Or does it choose between ARM and AVR?

I'm definitely gonna have a look at your code.
Oh well, yeah, isn't it like the same? Registers or Memory? In Code, both are just addresses, afaik

Thanks, again, this helped me a lot :)
But, this is exactly my goal, to write the lowest level code myself ^^ And I know it'll take time. But I'm okay with that
 
The Original Arduino stuff was working only on AVR based boards. Now Arduino itself sells a couple of different types of Arm boards M0 and M4, there is also STM32 setup, ESP32, ESP8... Robotis has their own board types for some of their controllers...

If you are interested in the mechanics of how to do this, you can search Arduino for for the documentation for it.

Note: Teensy does not fully follow the main way of installing as Paul's stuff replaces some of the features of Arduino releases. Like a better Serial monitor for the Teensy.

But the short hand version is for other systems. There are a set of board types that Arduino has setup, that you can install from the board manager, and this list can be extended by going to Arduino IDE preferences and edit the field: Additional Boards Manager URLs:

Then when you bring up board manager (tools->Boards->Board Manager), you will see a list of board types you can install, or remove or update...). Again Teensyduino does this different, in Paul releases Teensyduino that does the Board Manager stuff plus some updates.

When a board is defined, it can install and/or update tool sets. So for example I have latest installed at: c:\Arduino-1.8.13.
And under this is a directory Hardware/tools and under this are two sub-directories arm and avr which are installs of GCC stuff...

Also under Hardware is where Teensy is installed: .../hardware/teensy/avr
Where you find the cores and libraries folders with all of the core stuff and libraries included with Teensyduino.

Note: The directory names are important to some of the glue, there is also the branch .../hardware/Arduino/avr where all of the AVR stuff.
Note: in the teensy case avr is sort of misleading. Paul decided long ago not to separate out ARM and AVR for different reasons including he wanted many of the libraries installed to work with both platforms.

But back to the directory: .../hardware/teensy/avr
There are two important files that do the the glue:

boards.txt:
This populates the list of Teensy boards in the menu, and all of the options associated with it.
It also has stuff in it like what command to use for gcc, g++, ar, objcopy...

platform.txt:
This gives all of the recipes for building up all of the commands.

Again there are documents up on Arduino area that describe contents of these files and the like.

And Yes - Paul will startup to support some new board, example the T4. He will probably get something like one of their (STM) developement boards, and will then start of maybe adapting the bootloader stuff to be able to talk to it. He will also start doing a prototype board with the chip to start making a Teensy version with that chip. In the case with some of the first prototypes...

He will then startup doing the really low level stuff to get the board to boot up and start working. At some point when he has a prototype board and enough basic stuff working, he may produce a few of the prototype boards and an initial beta(alpha) Teensyduino for the board and then some of us try to help out as we can.

Hope that makes sense!
 
Also more side notes: If you use the Arduino hardware installer, the files are installed in a different location that is not independent of which Arduino you are using.
On Windows on my Windows 10 machine it installs different hardware at: C:\Users\kurte\AppData\Local\Arduino15\packages
Obviously your location will likely be different but it is your local... Arduino15
On my Linux machine: it is located at: ~/.arduino15

Again on my windows machine I have several different types of boards installed, so the sub-directory includes:
adafruit, arduino, esp8266, Intel, OpenCM904, OpenCR, SparkFun...

And if you look at for example the arduino directory, again there are two sub-directories:
hardware: which in my case has 3 subdirectories
avr
sam
samd
For three different types of boards two of which are ARM

The tools directories may contain again whole other versions of GCC compiler suites, which may be different versions and compile for different platforms.

Example the Intel one has intel i586 and i686 based boards

So again sorry for adding all of this non teensy information here, but I am trying to reinforce the idea that Arduino is not just 8 bit avr anymore.
 
Status
Not open for further replies.
Back
Top