CircuitPython on Teensy 4!

Hi all! I just wanted to drop by with a link to the circuitpython.org page for Teensy 4.0: https://circuitpython.org/board/teensy40/ Teensy 4.0 is included in the latest unstable release 5.0.0-beta.5. It will be included in the 5.0.0 stable release but the port will still be considered alpha.

circuitpython.org includes links to the latest and greatest CircuitPython releases for Teensy 4.0 (and all other boards). If you'd like to add more info to the page, it is also open source here: https://github.com/adafruit/circuitpython-org/blob/master/_board/teensy40.md

Thanks!
 
@tannewt
Very cool. Noticed that there is a link to UF2 on the Teensy 4 page. Can use just use the Hex or do we need to use UF2 now?
 
@mjs513 Use the hex for now and make sure to back up your files since the TeensyLoader erases the whole flash. I'll follow up here once we have a UF2 bootloader to try. (I've still got to figure out if we can trigger it easily too.)
 
Hi all! Just wanted to point out that CircuitPython 5.0.0 is out with Teensy 4.0 support. While the whole release is marked stable, I think the port is more in a beta state. What is there works pretty well but some APIs may not be implemented. Downloads are available here: https://circuitpython.org/board/teensy40/ Thanks!
 
I want to learn Python and Rust but I just keep putting it off. I hope this nudges me to give it a shot.
 
I want to learn Python and Rust but I just keep putting it off. I hope this nudges me to give it a shot.

Great! I've been meaning to try Rust on embedded as well! Let me know if you find any good tutorials. I'm also happy to help with any Python questions you have.
 
I just tried out CircuitPython for the first time on a Teensy 4.0 board and it was super easy to load and it just works. And there is one interesting feature that I first noticed on the AdaFruit page. If you have an iOS device with iOS13 then you can plug this into an iPhone/iPad and see the CIRCUITPY drive in the Files application. This doesn't happen with a Micro:bit. What is the secret which allows this to work? Perhaps the USB descriptor for the Micro:bit is asking for too much current? Anyways this is a good feature to have.
 
Using*https://www.thesycon.de/eng/usb_descriptordumper.shtml on Windows 10 (instead of lsusb because I was sitting at a Windows 10 machine)

Teensy - 0x32 bMaxPower * * *(100 mA)
Micro:bit - 0xFA bMaxPower * * *(500 mA)

On AdaFruit there is some text stating "Also, the device must have a USB descriptor that indicates it draws 100mA or less. Many USB descriptors say 500mA even if they don't use that much!"

So that's probably it. Thesycon’s descriptor dumper complained about some of the CircuitPython descriptors. It's been so long since I've looked at this stuff I don't have a strong opinion. I'll try to paste the whole dump here so you can take a look.

Code:
Information for device Teensy 4.0 (VID=0x239A PID=0x8086):

*** ERROR: Descriptor has errors! ***

Connection Information:
------------------------------
Device current bus speed: HighSpeed
Device supports USB 1.1 specification
Device supports USB 2.0 specification
Device address: 0x001E
Current configuration value: 0x00
Number of open pipes: 0

Device Descriptor:
------------------------------
0x12	bLength
0x01	bDescriptorType
0x0200	bcdUSB
0x00	bDeviceClass      
0x00	bDeviceSubClass   
0x00	bDeviceProtocol   
0x40	bMaxPacketSize0   (64 bytes)
0x239A	idVendor
0x8086	idProduct
0x0100	bcdDevice
0x02	iManufacturer   "PJRC"
0x03	iProduct   "Teensy 4.0"
0x01	iSerialNumber   "D110F7762D1770F1AC00000520002400"
0x01	bNumConfigurations

Device Qualifier Descriptor is not available. Error code: 0x0000001F

Configuration Descriptor:
------------------------------
0x09	bLength
0x02	bDescriptorType
0x0082	wTotalLength   (130 bytes)
0x04	bNumInterfaces
0x01	bConfigurationValue
0x00	iConfiguration
0xA0	bmAttributes   (Bus-powered Device, Remote-Wakeup)
0x32	bMaxPower      (100 mA)

Interface Association Descriptor:
------------------------------
0x08	bLength
0x0B	bDescriptorType
0x00	bFirstInterface
0x02	bInterfaceCount
0x02	bFunctionClass      (Communication Device Class)
0x02	bFunctionSubClass   (Abstract Control Model - ACM)
0x00	bFunctionProtocol   
0x00	iFunction

Interface Descriptor:
------------------------------
0x09	bLength
0x04	bDescriptorType
0x00	bInterfaceNumber
0x00	bAlternateSetting
0x01	bNumEndPoints
0x02	bInterfaceClass      (Communication Device Class)
0x02	bInterfaceSubClass   (Abstract Control Model - ACM)
0x00	bInterfaceProtocol   
0x04	iInterface   "CircuitPython CDC control"

CDC Header Functional Descriptor:
------------------------------
0x05	bFunctionalLength
0x24	bDescriptorType
0x00	bDescriptorSubtype
0x0110	bcdCDC

CDC Call Management Functional Descriptor:
------------------------------
0x05	bFunctionalLength
0x24	bDescriptorType
0x01	bDescriptorSubtype
0x01	bmCapabilities
0x01	bDataInterface

CDC Abstract Control Management Functional Descriptor:
------------------------------
0x04	bFunctionalLength
0x24	bDescriptorType
0x02	bDescriptorSubtype
0x02	bmCapabilities

CDC Union Functional Descriptor:
------------------------------
0x05	bFunctionalLength
0x24	bDescriptorType
0x06	bDescriptorSubtype
0x00	bControlInterface
0x01	bSubordinateInterface(0)

Endpoint Descriptor:
------------------------------
0x07	bLength
0x05	bDescriptorType
0x81	bEndpointAddress  (IN endpoint 1)
0x03	bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0040	wMaxPacketSize    (1 x 64 bytes)
0x10	bInterval         (32768 microframes)

Interface Descriptor:
------------------------------
0x09	bLength
0x04	bDescriptorType
0x01	bInterfaceNumber
0x00	bAlternateSetting
0x02	bNumEndPoints
0x0A	bInterfaceClass      (CDC Data)
0x00	bInterfaceSubClass   
0x00	bInterfaceProtocol   
0x05	iInterface   "CircuitPython CDC data"

Endpoint Descriptor:
------------------------------
0x07	bLength
0x05	bDescriptorType
0x02	bEndpointAddress  (OUT endpoint 2)
0x02	bmAttributes      (Transfer: Bulk / Synch: None / Usage: Data)
0x0040	wMaxPacketSize    (64 bytes)
0x10	bInterval         
*** ERROR: Invalid wMaxPacketSize. Must be 512 bytes in high speed mode.

Endpoint Descriptor:
------------------------------
0x07	bLength
0x05	bDescriptorType
0x82	bEndpointAddress  (IN endpoint 2)
0x02	bmAttributes      (Transfer: Bulk / Synch: None / Usage: Data)
0x0040	wMaxPacketSize    (64 bytes)
0x10	bInterval         
*** ERROR: Invalid wMaxPacketSize. Must be 512 bytes in high speed mode.

Interface Descriptor:
------------------------------
0x09	bLength
0x04	bDescriptorType
0x02	bInterfaceNumber
0x00	bAlternateSetting
0x02	bNumEndPoints
0x08	bInterfaceClass      (Mass Storage Device Class)
0x06	bInterfaceSubClass   (Transparent SCSI subclass)
0x50	bInterfaceProtocol   (Bulk only transport)
0x06	iInterface   "CircuitPython Mass Storage"

Endpoint Descriptor:
------------------------------
0x07	bLength
0x05	bDescriptorType
0x83	bEndpointAddress  (IN endpoint 3)
0x02	bmAttributes      (Transfer: Bulk / Synch: None / Usage: Data)
0x0200	wMaxPacketSize    (512 bytes)
0x00	bInterval         

Endpoint Descriptor:
------------------------------
0x07	bLength
0x05	bDescriptorType
0x03	bEndpointAddress  (OUT endpoint 3)
0x02	bmAttributes      (Transfer: Bulk / Synch: None / Usage: Data)
0x0200	wMaxPacketSize    (512 bytes)
0x00	bInterval         

Interface Descriptor:
------------------------------
0x09	bLength
0x04	bDescriptorType
0x03	bInterfaceNumber
0x00	bAlternateSetting
0x02	bNumEndPoints
0x03	bInterfaceClass      (Human Interface Device Class)
0x00	bInterfaceSubClass   
0x00	bInterfaceProtocol   
0x07	iInterface   "CircuitPython HID"

HID Descriptor:
------------------------------
0x09	bLength
0x21	bDescriptorType
0x0111	bcdHID
0x00	bCountryCode
0x01	bNumDescriptors
0x22	bDescriptorType   (Report descriptor)
0x00C3	bDescriptorLength

Endpoint Descriptor:
------------------------------
0x07	bLength
0x05	bDescriptorType
0x84	bEndpointAddress  (IN endpoint 4)
0x03	bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0040	wMaxPacketSize    (1 x 64 bytes)
0x08	bInterval         (128 microframes)

Endpoint Descriptor:
------------------------------
0x07	bLength
0x05	bDescriptorType
0x04	bEndpointAddress  (OUT endpoint 4)
0x03	bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0040	wMaxPacketSize    (1 x 64 bytes)
0x08	bInterval         (128 microframes)

Microsoft OS Descriptor is not available. Error code: 0x0000001F

String Descriptor Table
--------------------------------
Index  LANGID  String
0x00   0x0000  0x0409 
0x02   0x0409  "PJRC"
0x03   0x0409  "Teensy 4.0"
0x01   0x0409  "D110F7762D1770F1AC00000520002400"
0x04   0x0409  "CircuitPython CDC control"
0x05   0x0409  "CircuitPython CDC data"
0x06   0x0409  "CircuitPython Mass Storage"
0x07   0x0409  "CircuitPython HID"

------------------------------

Connection path for device: 
USB xHCI Compliant Host Controller
Root Hub
Teensy 4.0 (VID=0x239A PID=0x8086) Port: 2

Running on: Windows 10 or greater (Build Version 18362)

Brought to you by TDD v2.12.0, Aug  2 2019, 16:35:05
 
Last edited:
I just tried out CircuitPython for the first time on a Teensy 4.0 board and it was super easy to load and it just works. And there is one interesting feature that I first noticed on the AdaFruit page. If you have an iOS device with iOS13 then you can plug this into an iPhone/iPad and see the CIRCUITPY drive in the Files application. This doesn't happen with a Micro:bit. What is the secret which allows this to work? Perhaps the USB descriptor for the Micro:bit is asking for too much current? Anyways this is a good feature to have.

Yay! I'm glad it was easy and worked.

I'm not sure why the micro:bit doesn't appear as a drive. The max power could definitely be the issue. I'm not the one who looked into that.
 
Yay! I'm glad it was easy and worked.

I'm not sure why the micro:bit doesn't appear as a drive. The max power could definitely be the issue. I'm not the one who looked into that.

I was able to hack a Micro:bit build to lower the power requirements to 100 ma, however that was not sufficient. So I will have to study this some more.
 
It doesn't seem like @tannewt is on the Teensy 4.1 list. The forthcoming Teensy 4.1 looks like it would be a nice machine for Circuit Python, since it has a much larger flash memory than the Teensy 4.0, plus solder pads to add 2 more QSPI memory chips (one flash, one psram). Paul has said the official announcement will be in May.

I wonder how hard it would be to add the 4.1 support (obviously it wouldn't got into the Adafruit tree until the 4.1 is announced, but I could imagine people might want it after 4.1 becomes official). Note, I don't program in any form of Python, so I haven't done much with it. I verified that the Teensy 4.0 CP booted, and I've used a few CP programs others had written on some Adafruit boards.

https://forum.pjrc.com/threads/60532-Teensy-4-1-Beta-Test
Maybe you're curious about the specs? Teensy 4.1 uses the same 600 MHz IMXRT1062 microcontroller as Teensy 4.0. The PCB is the larger 48-pin form factor (same as Teensy 3.5 & 3.6), which provides more I/O pins and easier access the SD card and USB Host. Teensy 4.1 has an 8 MB flash chip, an Ethernet PHY, and places on the bottom side to solder QSPI memory chips.
 
It doesn't seem like @tannewt is on the Teensy 4.1 list. The forthcoming Teensy 4.1 looks like it would be a nice machine for Circuit Python, since it has a much larger flash memory than the Teensy 4.0, plus solder pads to add 2 more QSPI memory chips (one flash, one psram). Paul has said the official announcement will be in May.

I wonder how hard it would be to add the 4.1 support (obviously it wouldn't got into the Adafruit tree until the 4.1 is announced, but I could imagine people might want it after 4.1 becomes official).

It shouldn't be too hard to add! I don't have a 4.1 myself but I'd be happy review a PR to add it.
 
Whoa! Those numbers do look better! It'd be great to hunt down the TinyUSB bug so we can leave it on.

Re: enabling DCache on T4
Running some benchmarks (post #14) with T4 circuitpython v5.2.0, it appears the DCache is still not enabled. The bug in TinyUSB when using DCache may be related to cache management issues. The Teensy core has some support functions ( arm_dcache_delete(buff,nbytes), arm_dcache_flush_delete(buff,nbytes) ) for managing DMA/IO to/from cacheable memory. The Teensy audio library has code demonstrating the application of these functions. Maybe those cache functions can cure the TinyUSB bug???
 
We haven't done much work on the iMX RT ports in a while. Lucian is starting to work more on it this week though so we should see stuff mature. We've also updated the version of TinyUSB we use so it's possible that we can turn the DCache back on.

Thanks for checking in on the performance!
 
The installed circuit python for Teensy 4.1 gives you a 7 megabyte file system, compared to the 1 megabyte file system for Teensy 4.0.
 
using the CircuitPython 5.3.0.hex on a Teensy 4.1 the Mac said 13Meg? of space available until I tried a 8Meg file then no, and tried smaller until it successfully added a 990 KB file and said 25 KB available. So seems to be still 1Meg. Pretty fast though.

edit. I see I should have tried the 5.4 beta
 
I cobbled this from AdaF page:
Code:
import gc
print('Hello World!')
print('Hello World! T_4.0')
print (gc.mem_free())

It shows the same on T_4.0 as on the initial pre-test on T_4.1:
Code:
Press any key to enter the REPL. Use CTRL-D to reload.soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Hello World!
Hello World! T_4.0
[B]945296[/B]



Press any key to enter the REPL. Use CTRL-D to reload.

That number looks familiar - perhaps iot is the reserved space for storage noted above.

That from this partial post on T_4.1 beta thread:
...Read about MU install :: learn.adafruit … installing-mu-editor
Opened the code.py and edited and saved. Sent a Ctrl+D::
...
 
With CircuitPython 5.4.0.hex on a Teensy 4.1 the Mac said 7.3Meg available so I copied a 6.2Meg GIMP image file over in 1minute 9 secs. However it opened in about 4 seconds, from GIMP on my Mac, the same as my Mac hard drive. Also pretty neat (and weird !) running interactive python on the teensy in a terminal window. Reminds me of BASIC back in the day. (edit sorry @tannewt, you probably didn't appreciate that :))
 
That number looks familiar - perhaps iot is the reserved space for storage noted above.

That from this partial post on T_4.1 beta thread:

The RAM space that `gc.mem_free` shows should be the same on both Teensy 4.0 and 4.1 because it is the same microcontroller.

With CircuitPython 5.4.0.hex on a Teensy 4.1 the Mac said 7.3Meg available so I copied a 6.2Meg GIMP image file over in 1minute 9 secs. However it opened in about 4 seconds, from GIMP on my Mac, the same as my Mac hard drive. Also pretty neat (and weird !) running interactive python on the teensy in a terminal window. Reminds me of BASIC back in the day. (edit sorry @tannewt, you probably didn't appreciate that :))

Writing is greatly slowed by flash erase times.

Reminding you of BASIC is a complement. Many people got their start programming with BASIC and that's the goal with CircuitPython too.
 
Figured it was RAM though interesting to see all of that left in combination of RAM1 and RAM2. I suppose it was T_4.0 that had the 1MB due to flash size - so that grew.

I started on BASIC - got my degree - then first job initial projects were … interpreted BASIC ...
 
Ok since I am a gluten for punishment I decided to take it for a bit of a test spin using a ILI9341 and it does work. Didn't do any exhaustive testing. API and commands are similar but different but want to see if they would work and it does:

To do that first you have to download the circuit python libraries:
CircuitPython Libraries

Then add the Adafruit_ili9341.py file at the root: Adafruit_ili9341 lib

Then you can play with the ILI9341 examples files but also check this out first:
CircuitPython Display Support Using displayio

Also you might want to check the displayio API
 
I don't yet have a Teensy 4.1, just Teensy 4.0.

Any new feature of Teensy 4.1 (with respect Teensy 4.0) is implemented in CircuitPython 5.4.0-beta.0 for Teensy 4.1 ?
- internal 8MB flash memory seems recognized, with 7MB as file system, from post #93;
- all additional pins (to be confirmed);
- microSD (most important feature, IMHO) ?
- QSPI Memory via external PSRAM and/or flash chips ?
- USB host via Teensy 4.1's USB Host port ?
- Ethernet network via 10/100 Mbit Ethernet PHY ?

If not implemented, which features are planned to be ?
 
Back
Top