Teensy 4.0 & 4.1

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Teensy 4.0 & 4.1

Post by Roberthh » Wed Jun 23, 2021 10:13 am

Yes. That's still strange. What I will do is writing a little test script that dumps the values of all internal clocks. Maybe that gives a hint about what is changing. The speed change between -182 and -183 is repeatable forth and back with today's builds.

User avatar
RobH
Posts: 91
Joined: Fri Mar 23, 2018 3:37 pm
Location: Netherlands
Contact:

Re: Teensy 4.0 & 4.1

Post by RobH » Wed Jun 23, 2021 3:20 pm

Did several more builds from 1.15-177 up to 1.16-13. All give about 2620 pystones/second and all hex files are 728.9 KB. Also 1.15-182 and -183 were not exception: identical result.
I'm beginning to doubt if I followed the proper procedure. Before a new build I (only) issue a "git reset <7-digit-code>" and then start the build (preceded by make clean).
BTW: Where can I find the figure for code size?

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Teensy 4.0 & 4.1

Post by Roberthh » Wed Jun 23, 2021 4:01 pm

Generally i do the same:

git checkout <hash-value>
make clean
make BOARD=TEENSY40 -j5 deploy

The code size is reported at the end of the build. It is a table like this:

Code: Select all

Memory region         Used Size  Region Size  %age Used
  m_flash_config:         512 B         4 KB     12.50%
           m_ivt:          48 B         4 KB      1.17%
    m_interrupts:          1 KB         1 KB    100.00%
          m_text:      193084 B      1027 KB     18.36%
           m_vfs:          0 GB      1008 KB      0.00%
      m_reserved:          0 GB         4 KB      0.00%
          m_itcm:        1964 B       128 KB      1.50%
          m_dtcm:       42160 B       128 KB     32.17%
          m_ocrm:          0 GB       768 KB      0.00%
   text	   data	    bss	    dec	    hex	filename
 196632	    256	  40112	 237000	  39dc8	build-TEENSY40/firmware.elf
I made several attempts to find a reason, but no luck. The clock settings are always identical, and the memory settings as well. It looks like a random choice, as if it depends on some data randomly set in RAM.

The hash code for build 182 is a40e1473d, the one for 183 is bbdc98f72

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Teensy 4.0 & 4.1

Post by Roberthh » Wed Jun 23, 2021 6:43 pm

I am almost sure that the differences we see are related to the Python dynamic memory management. I ran another test which was provided a while ago by @pythoncoder, which just does arithmetic and a little bit of looping. There, the numbers are consistent over all versions. That matches my observation when using the port, that there is no noticeable difference over the various versions. Peter's test script:

Code: Select all

import time
import machine

def pi(places=100):
  # 3 + 3*(1/24) + 3*(1/24)*(9/80) + 3*(1/24)*(9/80)*(25/168)
  # The numerators 1, 9, 25, ... are given by (2x + 1) ^ 2
  # The denominators 24, 80, 168 are given by (16x^2 -24x + 8)
  extra = 8
  one = 10 ** (places+extra)
  t, c, n, na, d, da = 3*one, 3*one, 1, 0, 0, 24

  while t > 1:
    n, na, d, da = n+na, na+8, d+da, da+32
    t = t * n // d
    c += t
  return c // (10 ** extra)

def pi_test(n=5000):
    t1=time.ticks_ms()
    t=pi(n)
    t2=time.ticks_ms()
    print('Pi test: ', time.ticks_diff(t2,t1)/1000, 's')

def pass_test(n=1000000, a = 1234, b = 5678):
    t1=time.ticks_ms()
    sum = 0
    for i in range(n):
        pass
    t2=time.ticks_ms()
    print('Pass test: ', time.ticks_diff(t2,t1)/1000, 's')

@micropython.native
def passn_test(n=1000000, a = 1234, b = 5678):
    t1=time.ticks_ms()
    sum = 0
    for i in range(n):
        pass
    t2=time.ticks_ms()
    print('Pass test native: ', time.ticks_diff(t2,t1)/1000, 's')

def add_test(n=1000000, a = 1234, b = 5678):
    t1=time.ticks_ms()
    sum = 0
    for i in range(n):
        sum = a + b
    t2=time.ticks_ms()
    print('Add test: ', time.ticks_diff(t2,t1)/1000, 's')

@micropython.native
def addn_test(n=1000000, a = 1234, b = 5678):
    t1=time.ticks_ms()
    sum = 0
    for i in range(n):
        sum = a + b
    t2=time.ticks_ms()
    print('Add test native: ', time.ticks_diff(t2,t1)/1000, 's')

def mul_test(n=1000000, a = 1234, b = 5678):
    t1=time.ticks_ms()
    sum = 0
    for i in range(n):
        sum = a * b
    t2=time.ticks_ms()
    print('Mul test: ', time.ticks_diff(t2,t1)/1000, 's')

def div_test(n=1000000, a = 1234, b = 5678):
    t1=time.ticks_ms()
    sum = 0
    for i in range(n):
        sum = a / b
    t2=time.ticks_ms()
    print('Div test: ', time.ticks_diff(t2,t1)/1000, 's')

def idiv_test(n=1000000, a = 1234, b = 5678):
    t1=time.ticks_ms()
    sum = 0
    for i in range(n):
        sum = b // a
    t2=time.ticks_ms()
    print('iDiv test: ', time.ticks_diff(t2,t1)/1000, 's')


print('Speed test')
try:
    print('System freq: {:.1f} MHz'.format(machine.freq()[0]/1000000))
except:
    print('System freq: {:.1f} MHz'.format(machine.freq()/1000000))

pass_test()
passn_test()
add_test()
add_test(1000000, 1234.1, 5678.1)
addn_test()
addn_test(1000000, 1234.1, 5678.1)
mul_test()
mul_test(1000000, 1234.1, 5678.1)
div_test()
div_test(1000000, 5678.1, 1234.1)
idiv_test()
pi_test()
Note: For versions before 1..15-183 you have to comment the decorator. Support for that came with 1.15-183.
And some results:

Code: Select all

MicroPython v1.16-19-g8b1d75b8d on 2021-06-23
System freq: 600.0 MHz
Pass test:  0.443 s
Pass test native:  0.215 s
Add test:  0.641 s
Add test:  1.367 s
Add test native:  0.277 s
Add test native:  1.219 s
Mul test:  0.693 s
Mul test:  1.377 s
Div test:  1.369 s
Div test:  1.443 s
iDiv test:  0.677 s
Pi test:  2.211 s


MicroPython v1.15-182-ga40e1473d on 2021-06-23
System freq: 0.0 MHz
Pass test:  0.447 s
Add test:  0.64 s
Add test:  1.363 s
Mul test:  0.697 s
Mul test:  1.373 s
Div test:  1.189 s
Div test:  1.439 s
iDiv test:  0.675 s
Pi test:  2.017 s


MicroPython v1.15-183-gbbdc98f72 on 2021-06-23
System freq: 600.0 MHz
Pass test:  0.447 s
Pass test native:  0.221 s
Add test:  0.64 s
Add test:  1.366 s
Add test native:  0.286 s
Add test native:  0.907 s
Mul test:  0.697 s
Mul test:  1.384 s
Div test:  1.201 s
Div test:  1.447 s
iDiv test:  0.675 s
Pi test:  2.124 s
Some earlier results with ESP32 and PybD-SF6

Code: Select all

Runtest, ESP32 with spiram

Speed test
System freq: 240.0 MHz
Add test:  3.514 s
Mul test:  3.703 s
Div test:  7.758 s
Pi test:  16.149 s

Runtest, ESP32 without spiram, firmware with spiram support
Speed test
System freq: 240.0 MHz
Add test:  3.225 s
Mul test:  3.418 s
Div test:  4.599 s
Pi test:  11.29 s

Runtest, ESP32 without spiram, firmware without spiram support
Speed test
System freq: 240.0 MHz
Add test:  3.064 s
Mul test:  3.255 s
Div test:  4.368 s
Pi test:  9.005 s

MicroPython v1.9.4-793-gaba83e66-dirty on 2019-02-05; ESP32 module with ESP32
Runtest, ESP32 without spiram, firmware without spiram support
Speed test
System freq: 240.0 MHz
Add test:  2.625 s
Mul test:  2.809 s
Div test:  15.874 s
Pi test:  8.354 s

PyBoard D SF6. 
MicroPython v1.16-13-gc99e4995f on 2021-06-23
Speed test
System freq: 192.0 MHz
Pass test:  1.089 s
Pass test native:  0.6680000000000001 s
Add test:  1.704 s
Add test:  4.248 s
Add test native:  0.893 s
Add test native:  2.933 s
Mul test:  1.881 s
Mul test:  4.258 s
Div test:  3.562 s
Div test:  4.46 s
iDiv test:  1.818 s
Pi test:  7.073 s
:

User avatar
RobH
Posts: 91
Joined: Fri Mar 23, 2018 3:37 pm
Location: Netherlands
Contact:

Re: Teensy 4.0 & 4.1

Post by RobH » Thu Jun 24, 2021 12:22 pm

I've run Peter's script and see generally comparable figures with yours, but also some significant(?) differences.
Below 2 runs, the second with a one of my 'fast' firmware versions (4200 pystones)
  • Pi test is always around 3.5 with me, even with the fast firmware
  • Add test native is mostly 0.9, but I saw also 1.7 and 3.5 (with the same firmware).
This performance analysis is interesting, but it takes quite some time! It might also be a little premature in the current stage of development of this port. I would like to take a pause and maybe pick it up again later.

Code: Select all

MicroPython v1.16-13-gc99e4995f-dirty on 2021-06-24; Teensy 4.0 with MIMXRT1062DVJ6A
Speed test
System freq: 600.0 MHz
Pass test:  0.44 s
Pass test native:  0.34 s
Add test:  0.636 s
Add test:  1.386 s
Add test native:  0.276 s
Add test native:  3.508 s
Mul test:  0.694 s
Mul test:  1.409 s
Div test:  1.966 s
Div test:  1.454 s
iDiv test:  0.673 s
Pi test:  3.699 s

MicroPython v1.15-216-g95048129b on 2021-06-18; Teensy 4.0 with MIMXRT1062DVJ6A
Speed test
System freq: 600.0 MHz
Pass test:  0.443 s
Pass test native:  0.215 s
Add test:  0.637 s
Add test:  1.797 s
Add test native:  0.277 s
Add test native:  0.902 s
Mul test:  0.694 s
Mul test:  1.81 s
Div test:  1.699 s
Div test:  1.504 s
iDiv test:  1.075 s
Pi test:  3.431 s

User avatar
RobH
Posts: 91
Joined: Fri Mar 23, 2018 3:37 pm
Location: Netherlands
Contact:

Re: Teensy 4.0 & 4.1

Post by RobH » Sun Jun 27, 2021 6:04 pm

The ST7789 TFT display works fine and much faster with the new hardware SPI!
I'm looking forward to support VfsFat to be able to drive an SD card! ;-)

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Teensy 4.0 & 4.1

Post by Roberthh » Sun Jun 27, 2021 6:22 pm

SDCard support is still under construction. You can use it with SoftSPI and the Python driver. But for that, FAT support has to be included.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Teensy 4.0 & 4.1

Post by Roberthh » Sun Jun 27, 2021 8:25 pm

Here is a firmware package that includes the FAT support. You can use that with SPI to connect a SD card. It also support a regular SD card at the SD card pins on the bottom side. But that is still under development.
https://hidrive.ionos.com/lnk/P4CAiRPM Teensy 4.0
https://hidrive.ionos.com/lnk/n4CgCMDd Teensy 4.1

User avatar
RobH
Posts: 91
Joined: Fri Mar 23, 2018 3:37 pm
Location: Netherlands
Contact:

Re: Teensy 4.0 & 4.1

Post by RobH » Thu Jul 15, 2021 3:03 pm

I noticed the addition of hardware I2C, great!
I did some elementary tests with a board which uses 2 I2C interfaces (with a.o. tcs34725 and tsl2591). All works fine!
However I noticed an issue with I2C.init(). A change of freq (what else could be changed with hardware-I2C?) shows:

Code: Select all

MicroPython v1.16-92-g98c570302-dirty on 2021-07-15; Teensy 4.0 with MIMXRT1062DVJ6A
Type "help()" for more information.
>>> from machine import I2C
>>> bus = I2C(0)
>>> bus.init(freq=100000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: I2C operation not supported
Similarly with PyBoard:

Code: Select all

MicroPython v1.16-92-g98c570302-dirty on 2021-07-15; PYBv1.1 with STM32F405RG
Type "help()" for more information.
>>> from machine import I2C
>>> bus=I2C(1)
>>> bus.init(100000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: I2C operation not supported
In both cases dir(machine.I2C) shows the presence of 'init'. So what is the reason for this?

With SoftI2C (with the Teensy 4.0) another issue with init():

Code: Select all

MicroPython v1.16-92-g98c570302-dirty on 2021-07-15; Teensy 4.0 with MIMXRT1062DVJ6A
Type "help()" for more information.
>>> from machine import SoftI2C, Pin
>>> bus=SoftI2C(scl=Pin("A2"), sda=Pin("A3"))
>>> bus.init(freq=100000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'scl' argument required
{/code]

Why is 'scl' (and probably 'sda') a required argument?

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Teensy 4.0 & 4.1

Post by Roberthh » Thu Jul 15, 2021 3:25 pm

Both Hardware and Software I2c share the same dictionary. The hardware i2c has no init() method, that's why you get that message. You can simply instantiate the I2c again for a frequency change. That is not an expensive operation. I was thinking of implementing a separate init() method, but followed the example of other ports not to do that.
The softI2C code is not touched with the new hardware I2C. So whatever you notice now, must have been there before. Looking into the code, it's the same code used for soft_i2c_new and soft_i2c_init. That's why sda and sdl are told to be mandatory. But that should apply to all ports.

Post Reply