CircuitPython on Teensy 4!

Though why Python can't give microsecond precision delay is also a good question. Arduino supports delayMicroseconds() on all boards. The slower boards usually have a minimum delay of several microseconds, so it's far from perfect, but certainly a lot better than 1 millisecond resolution.

The delay could be more accurate but we run "background" stuff between Python byte codes. We may do mass storage writes, for example, that will mess up any precision timing. So, it's best to not rely on the timing of Python code execution.


Thank you!
 
@tannewt
I had a chance to install the .hex on the T4 the other day using the Teensy Loader to upload the file on a Windows10x64 PC. After upload Windows install it as a new drive and I was able to run Putty to access CircuitPython without have to unplug it and replug it back in - think you mentioned this in your first post. Tried TyCommander as well and no problem.

As for adjust the clock and I can take a look if you point me in the right direction. Looks like its in mircrocontroller - clock.c file? In the Teensy 4 core there is a file clockspeed.c that probably has what is needed to be put into circuitpython.
 
@tannewt
I had a chance to install the .hex on the T4 the other day using the Teensy Loader to upload the file on a Windows10x64 PC. After upload Windows install it as a new drive and I was able to run Putty to access CircuitPython without have to unplug it and replug it back in - think you mentioned this in your first post. Tried TyCommander as well and no problem.

As for adjust the clock and I can take a look if you point me in the right direction. Looks like its in mircrocontroller - clock.c file? In the Teensy 4 core there is a file clockspeed.c that probably has what is needed to be put into circuitpython.

Glad it worked well! Sounds like you found the right place. We already provide microcontroller.cpu.frequency as a read-only value. (The API is here: https://github.com/adafruit/circuit...ared-bindings/microcontroller/Processor.c#L57 ) It'd be awesome to make it writable. Then the implementation can try to change the speed and either return the new value on the next read or the old value if it failed. The general file layout is documented here: https://circuitpython.readthedocs.io/en/4.x/docs/common_hal.html and build instructions are here: https://learn.adafruit.com/building-circuitpython/

Thanks!
 
@tannewt
I have successfully built circuitpython for STM32F405 (increased CPU clock to 168mhz) , but my build failed starting from your branch
https://github.com/tannewt/circuitpython/tree/teensy4
I followed the steps described at https://learn.adafruit.com/building-circuitpython
but make BOARD=teensy40 fails with
make: *** No rule to make target 'lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c'

thoughts?

I'm not sure the tip of my branch builds atm. I'm reworking the linking right now.

That error sounds like the TinyUSB submodule isn't updated fully. Make sure to `git submodule sync` and `git submodule update --init .` when switching branches.
 
OK, i did those git submodule, and that ends with
Code:
...
error: Server does not allow request for unadvertised object cf3acd6b6d47e3aaeb0ca29a70ca1339d415908b
Fetched in submodule path 'ports/mimxrt10xx/sdk', but it did not contain cf3acd6b6d47e3aaeb0ca29a70ca1339d415908b. Direct fetching of that commit failed.
then the make fails with

Code:
make BOARD=teensy40
Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity.
Traceback (most recent call last):
  File "../../tools/gen_usb_descriptor.py", line 8, in <module>
    from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util
ModuleNotFoundError: No module named 'adafruit_usb_descriptor'
../../supervisor/supervisor.mk:185: recipe for target 'autogen_usb_descriptor.intermediate' failed
make: *** [autogen_usb_descriptor.intermediate] Error 1
 
I was watching thjis weeks Ask an Engineer (1/15/2020) from Adafruit, and they had a big mention about Circuit Python on the Teensy 4.0

  • https://www.facebook.com/adafruitindustries/videos/585329442079046/
  • The main discussion starts at the 14 minutes, 10 seconds and goes through about 17 minutes and 30 seconds (with a little preview of a future feather that followed the Teensy stuff).
  • FWIW, there 10% off code for the day was IotTeensy.
  • I was amused the 2 issues Limor mentioned was the I2C and SPI buses were faster than the devices she was attaching.

I know the Teensy 4.0++ will have places to solder flash memory on the chip. It may be useful in terms of sales particularly to some of the CircuitPython people if there was a version that has the flash memory soldered in (along with the pins being soldered).

As an aside, the reason I was tuning in today was I'm on some electronics panels this weekend and one of my older projects is a simple Neopixel ring on a wooden bowtie. I've built it twice using the Teensy LC (due to the tri-state buffer for Neopixels). My main board stopped working due to broken solder joints. I tried to resolder the joints, and pulled off the copper on the prototype board. The second LC also was getting cranky in terms of solder joints and the layout wasn't the greatest.

I discovered I no longer had any unsoldered LC's, but in thinking about it, I really wanted the on/off feature of the Teensy 4.0 (rather than hacking in an on/off switch), so the next board will have the Teensy 4.0 + Adafruit Feather (for the JST lipo battery charger). So, I'm ordering another Teensy 4.0. :)
 
Last edited:
- CircuitPython halts after :
Code:
import microcontroller
microcontroller.cpu.temperature

likely TEMPMON fix described in github issue

FYI, circuitpython T4 register settings:
Code:
SystemCoreClock 600000000  14:17:35 Jan 16 2020 ok

AhbClk 600000000  kCLOCK_RtcClk 32768  kCLOCK_Usb1PllPfd0Clk 360000000  kCLOCK_IpgClk 150000000
kCLOCK_Usb1PllClk 480000000  kCLOCK_OscClk 24000000 CoreSysClk 600000000 ARMPLL 1200000000
XTALOSC24M->LOWPWR_CTRL 0x74f01
XTALOSC24M->OSC_CONFIG0 0x4002040
XTALOSC24M->OSC_CONFIG1 0x2ee
XTALOSC24M->OSC_CONFIG2 0x800102e2
SCB->ICIALLU 0x0
SCB->CCR 0x60200
SCB->CSSELR 0x0
SCB->CCSIDR 0xf01fe019
SCB->DCISW 0x0
SCB->CCR 0x60200
CCM->CBCDR 0xf8300
SNVS->LPCR 0x21
SNVS->LPSRTCMR 0x2f10
SNVS->LPSRTCLR 0x3856f8ea
CCM_ANALOG->MISC0 0x24008080
SysTick->CTRL 0x7
SysTick->LOAD 0x927be
CCM->CCGR0 0xc0000fff
CCM->CCGR1 0xfc0cc000
CCM->CCGR2 0xc3fc033
CCM->CCGR3 0xf00ff300
CCM->CCGR4 0xffff
CCM->CCGR5 0xf0033c33
CCM->CCGR6 0xfc3fc3
CCM->CMEOR 0x7fffffff
CCM->CSCMR1 0x45100001
SysTick->LOAD should really be 0x927bf, filed issue
 
Last edited:
Hi all! I wanted to post an update. I spent all week heads down on rejiggering CircuitPython to take advantage of the TCM and caches better. It looks to be a 10ish times speedup for a very simple Python program.

I've opened a pull request for Teensy 4.0 support here: https://github.com/adafruit/circuitpython/pull/2532

I've also attached a new build. Please make sure and back up your files before updating with TeensyLoader! I'm not sure whether the files get wiped or not.

Thanks!
 

Attachments

  • circuitpython-teensy40-1c39606.hex.zip
    266 KB · Views: 148
I tried your latest .hex. REPL prints a bunch of eeeeeeee's when it starts up. Also confirm REPL consumes the first character typed ? Strange behavior on a couple of py scripts that work fine with previous release. fact.py prints 0 seconds ? -- previous version reports 0.00488281s seconds, though your "speedup" could drive that to 0 with only millisecond resolution. llutm.py says SyntaxError: invalid syntax but runs ok with previous .hex. Another script, raytrace.py, also fails with SyntaxError: invalid syntax but works on your previous release and works with python3 on linux????

microcontroller.cpu.temperature still hangs -- there is a "fix" for that: https://github.com/adafruit/circuitpython/issues/2514

toggle.py is faster 379khz, period 2.64 us (scope)
 
Last edited:
Ahh thank you. I thought you meant to get back to the basic Arduino environment. This would be my first try at Circuit Python so I have nothing to backup. If I ever get past ground zero I want to get good at Circuit Python to bang out a quick make it work prototype and then try to convert to Rust and save Arduino for when there is no drivers or libraries I need for the other two. At 800 mhz Circuit Python will probably faster than I need anyway.
 
Re: T4 microsecond timer

since microcontroller.cpu.voltage wasn't doing anything useful, I hacked common-hal/microcontroller/Processor.c to make voltage use GPT2 to return seconds to micro-second resolution.
Code:
float common_hal_mcu_processor_get_voltage(void) {
    // GPT2 micros
    static int do_init = 1;
    if (do_init) {
        do_init = 0;
 //     SCB_EnableDCache();
        CLOCK_EnableClock(kCLOCK_Gpt2);
        GPT2->CR = 0;
        GPT2->PR = 75-1;  
        GPT2->SR = 0x3F;  // clear
        GPT2->CR = GPT_CR_FRR_MASK | GPT_CR_CLKSRC(1) | GPT_CR_EN_MASK;
    }
    return GPT2->CNT/1000000.;
    //return NAN;
}

>>> t1 = microcontroller.cpu.voltage;time.sleep(1); t2 = microcontroller.cpu.voltage; t2-t1
0.999512

CCM->CSCMR1 0x45100001 implies GPT running at @150/2 mhz

option: enable DCache
 
Last edited:
I tried your latest .hex. REPL prints a bunch of eeeeeeee's when it starts up. Also confirm REPL consumes the first character typed ? Strange behavior on a couple of py scripts that work fine with previous release. fact.py prints 0 seconds ? -- previous version reports 0.00488281s seconds, though your "speedup" could drive that to 0 with only millisecond resolution. llutm.py says SyntaxError: invalid syntax but runs ok with previous .hex. Another script, raytrace.py, also fails with SyntaxError: invalid syntax but works on your previous release and works with python3 on linux????

microcontroller.cpu.temperature still hangs -- there is a "fix" for that: https://github.com/adafruit/circuitpython/issues/2514

toggle.py is faster 379khz, period 2.64 us (scope)

Thanks for testing with the latest hex! I've gotta spend time on other things this week so I think I'll disable the DCache for now which is my guess at the USB problem. I've opened an issue to fix it later here: https://github.com/adafruit/circuitpython/issues/2537

Ahh thank you. I thought you meant to get back to the basic Arduino environment. This would be my first try at Circuit Python so I have nothing to backup. If I ever get past ground zero I want to get good at Circuit Python to bang out a quick make it work prototype and then try to convert to Rust and save Arduino for when there is no drivers or libraries I need for the other two. At 800 mhz Circuit Python will probably faster than I need anyway.

Cool cool. :) Most of the CircuitPython boards won't wipe the CIRCUITPY file system on CircuitPython upgrade so I wanted to make sure and point out that the Teensy version might. Have the Rust folks started adding iMX RT support yet? I'm sure they will. I'd love to start using Rust for bits of CircuitPython too. I just haven't found the right tutorial on how to slowly migrate embedded C over to Rust.
 
I can confirm Teensy Loader erases all but the top 64K of flash (4K of which is the read-only restore image) when you load any new .hex file.

This is meant as a security feature for people who create commercial proprietary products using Teensy. They do not wish for their code to be easily captured & cloned. If Teensy Loader were to erase only as much flash as your .hex file uses, then you could capture most of anyone's large program by loading only a very small program which reads the rest of the flash and sends it to a serial port. To prevent this sort of attack, the entire space for program storage is fully erased before any of the new hex file data is written.
 
Thanks Paul! We'll make a UF2 bootloader available that will run after the TeensyLoader and make it easier to load just the CircuitPython part of flash.
 
Back
Top