Teensy 4.0 First Beta Test

Status
Not open for further replies.
@mjs - i dont' see any lines that set 44100 Hz here.. can you measure the LRCLK?
Nope. I just put a scope on the pin 23, and using the rest of @wmxz code (made a bad assumption here). With his clk code I get 23.8Mhz/24.39Mhz with the sdk code I get 24.39/25Mhz. Have to go find the code that brings I down to 44.1khz. Then I will let you know. Any hints?
 
@Frank
I implemented the clock function that I posted to test what frequency it was giving me versus what @WMXZ code gave me:
Code:
WMXZ   -  AudioPll Clock: 768000000
SDK      -  AudioPll Clock: 786480000
The 2 are close but the sdk is what I believe is recommended.

EDIT: Haven't put a scope on the clk pin yet - have to set it up - don't exactly have much room on my desk to keep it setup permanently

Cannot say what should be recommended.
The value I have chosen was to get sampling frequencies of say multiple of 48 kHz and not 44.1 kHz.
any-how the PLL should run at a multiple of the MCLK
and the SAI Pre divider should bring the clock below 300 MHz
 
Have uploaded a first version to https://github.com/FrankBoesing/audio_imxrt

The only output working is I2s -tested with the audio-shield. Inputs: None :)
Copy the files in TEENSY4_CORE to the T4-core..

There are many files that have
Code:
#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__)
All these need some work.

Currently, it's set to 44100Hz (PLL 903168000Hz)

My testsketch:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform    waveform1;
AudioOutputI2S        i2s1;
AudioConnection       patchCord1(waveform1, 0, i2s1, 0);
AudioConnection       patchCord2(waveform1, 0, i2s1, 1);
AudioControlSGTL5000  sgtl5000_1;
// GUItool: end automatically generated code

void setup() {
  AudioMemory(15);
  delay(1000);
  Serial.println("Start Audio");
  
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.2);  
  Serial.println("SGTL INITIALIZED");
  
  waveform1.begin(WAVEFORM_SINE);
  waveform1.frequency(440);
  waveform1.amplitude(0.99);  
  
}

void loop() {}

Tested with both I2S.

Many thanks to WMXZ!

Edit:
I'll add PT8211 this weekend and maybe begin work on SPDIF-Out
 
Last edited:
SPI Transfer Asynch - Pull request - https://github.com/PaulStoffregen/SPI/pull/45

Could always use some additional testing.

I put the tests in for address >= 0x20200000 and either flush(TX) or delete(RX) cache for those addresses. Made output look better in test app.

Maybe I will hack up my version of the SSD1306 driver I did for FlexIO and add an Asynch update display function, and also add back in the ability to use SPI library here... Assuming that works, will then play with DMA transfer for FLEXio...
 

Attachments

  • SPI_Transfer_test-190131b.zip
    1.7 KB · Views: 84
KurtE - what would a test for SPI Asynch Xfer look like?

I just updated posts# 4 & 6 to account for micros() now working with 1 us resolution based on cycle counter - no more 10us resolution, @FrankB pulseIn can be tested with that.

re: debug_tt library [Teensy Trace] - anyone with a T4 see value in what I've started?
>> Other than catching faults - and '** Display' trace/logged info and allowing call to a user function to dump or do whatever you want to examine the state at time of fault it isn't 'magic'
>> Though in .begin() a pin can be specified for interrupt to stop execution and allow ** Display
>> The other things codified just allow ways to track and log or display entry to functions and values at that time/location
>> The non-display functions are interrupt safe so other than some cycles to log info - it just returns for later review
>> Display functions are just shortcuts often with macros to simplify printing in a single line of code.
>> All calls() have _tt in the name to find them quickly for attention or removal.
>> Everything is covered with a macro ( except fault handler ) so it can be removed with a #define for normal execution.
>> Ideas to add to make it useful the way you debug?

I made a keywords.txt for IDE color coding. It is all 'C' since the fault handler is - so no classy stuff. Quick summary of the keywords:
FUNCTIONS in keywords.txt::
----- conditional break of execution with display to SerMon and prompt
assert_tt( expression ) :: the expression is tested and if FALSE breaks in to the debug code for ** Display
haltif_tt( expression ) :: the expression is tested and if TRUE breaks in to the debug code for ** Display
** Display allows Teensy to bootloader, dumping other info as desired rather than always doing SPEW with call to user Debug_Dump()
----- displays to SerMon with a simple command to see
where_tt() :: Send a line of debug output to monitor showing:: Function name and line number and the address of a stack variable for reference
addr_tt(a) :: Shows the HEX memory address of the provided memory object
debText_tt(a) :: Prints the code line # and the value provided
debText2_tt( a, b ) :: Prints the code line # and the two values provided
----- Logs to RAM for later display
deb_tt( a, b) :: Logs a setpoint in the storage array for the indicated value a and stores the uint32_t value, also records the line number and function
debBegin_tt :: Provides needed Begin values for the library
debTraceShow_tt :: Display the trace log
debTrace_tt :: Records a Trace entry

I've not gotten enough feedback to date to justify my finishing it enough to start a thread for it . . .
 
Have uploaded a first version to https://github.com/FrankBoesing/audio_imxrt

The only output working is I2s -tested with the audio-shield. Inputs: None :)
Copy the files in TEENSY4_CORE to the T4-core..

There are many files that have
Code:
#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__)
All these need some work.

Currently, it's set to 44100Hz (PLL 903168000Hz)

My testsketch:
Code:
...

Tested with both I2S.

Many thanks to WMXZ!

Edit:
I'll add PT8211 this weekend and maybe begin work on SPDIF-Out

Frank
Just loaded everything up and ran your test sketch. Obviously it worked. I did get about a 11.26Mhz MCLK and a 44.09/44.11kHz for LRCLK.

Only problem I see is that it takes a very long time to upload the sketch, over 3 minute. Compile went fast a couple of seconds. First time I've seen this happen. trying tone sweep now..

EDIT: Did get tonesweep and Guitar to work.
 
Last edited:
Indeed the 1062 extra RAM is important to allow buffer space to minimize moving the data elsewhere at inopportune times, but even so half of RAM gets wait stated. What does a memcpy from FLASH look like timewise?

I saw faster GPIO noted - will be good to see that work out.

Re: GPIO performance on 1062

I ran some pin toggle tests on NXP EVKB(1052) and on the NXP 1062 eval board. We count cycles for 8 pin toggles with pin hooked to scope.
Code:
    cycles = ARM_DWT_CYCCNT;
    GPIO1->DR_TOGGLE = 1<<19;   // pin 7
    GPIO1->DR_TOGGLE = 1<<19;
    GPIO1->DR_TOGGLE = 1<<19;
    GPIO1->DR_TOGGLE = 1<<19;
    GPIO1->DR_TOGGLE = 1<<19;
    GPIO1->DR_TOGGLE = 1<<19;
    GPIO1->DR_TOGGLE = 1<<19;
    GPIO1->DR_TOGGLE = 1<<19;
    cycles= ARM_DWT_CYCCNT -cycles;
On the NXP 1052 it takes 169 cycles, and the scope shows
m7toggle.png
This matches luni's T4 scope shot on post #1222 with a period of 106 ns.

The same sketch on the NXP 1062 is faster (85 cycles), but not as fast as I might have hoped. The scope shot shows a period of 53 ns.
m62toggle.png

Perhaps, my test is flawed.

EDIT: Yep, test is flawed. Need to figure out how to use GPR26 and GPIO6 ...

EDIT 2:
OK, the fast GPIO on GPIO6-8 looks good. My scope is probably the limiting factor. So with 10 nop's between toggles I have a nice sine wave on scope (49 Mhz, period 20.4 ns, Vpp 1.68v). Faster toggle rates reduces the Vpp to a ripple. My testing was hampered by NXP's API GPIO_PinInit(GPIO6, 19, &led_config) which caused hard fault, so I had to use GPIO6->GDIR = 1<<19, toggling with GPIO6->DR_TOGGLE = 1<<19. And before setting GDIR, enable the fast GPIO with GPIO6 IOMUXC_GPR->GPR26 |= 1<<19. The GPIO6-8 share the PAD settings for GPIO1-3. Spec rate of 150mhz.

For write/read/write times see post #1404
 
Last edited:
KurtE - what would a test for SPI Asynch Xfer look like?
Many different ways. The test sketch I uploaded as part of the previous message, has calls to do Sync and Async calls to SPI.transfer. There are calls that do Write only, Read only (sends dummy char default 0), or full transfers.

The code internally is setup to do copy of up to 32767 bytes per transfer, if user specifies more, the ISR that triggers at the DMA will restart the DMA operation to continue it... Could have chained requests, but...

For Teensy 3.5/6 I had a version of Teensyview that had option to do asynch updates. At the time I had tests running where I had multiple displays being updated, one on each SPI buss... But only have one BUS and obviously can only do DMA to one of the devices at a time on the same SPI buss...

But I am setting up my hacked up Adafruit_SSD1306 library to allow the use of the Async update... Will then be a fun test to try updating one on the Hardware SPI buss and one on FLEX IO buss...

At one point, I had a version of my ili9341_t3n library (_t3ns), that had the frame buffer and instead of using all of the SPI FIFO queue stuff like the _t3 or _t3n does it used SPI calls...

However at the time I had it using a version of the transfer that Paul did not want in the library: 16 bit buffer transfer:
_spi->transfer16(_pfbtft, NULL, _width*_height); // blast it out.

or:
_spi->transfer16(_pfbtft, NULL, _width*_height, _event_responder); // blast it out.

So I have not touched this one in awhile. I could probably have hacked up the backing memory to reverse the color bytes so we could just use transfer...
 
Many different ways. The test sketch I uploaded as part of the previous message, has calls to do Sync and Async calls to SPI.transfer.
...

Okay I got the sketch - the zip had that … now to go find the updated SPI code … https://github.com/KurtE/SPI/tree/T4_Async_Support

<edit> :: Sketch Tests ran without indicated error and looked fine.

Let me know when you have a TeensyView lib ready I've got one here on the desk looking very [bread]Bored :) Interesting to see if it works - it has a crack in the glass.
 
Last edited:
@Paul - when I compile sometimes it is done and uploaded in ~5 secs. Other times the File save isn't shown done for 5 secs or 50 seconds to even start the compile. Maybe my SSD is funny? Or could it be T_ports?
I was going to ask when T_ports is queried and realized it is probably just before a connected T_sermon to T4 is set Offline - sure enough watching the title bar the compile doesn't start until T_sermon is [offline].
I think I've seen this sluggish behavior with no code changes - just doing Ctrl+U to get an Upload+Restart - but of course trying 20 Ctrl+U with no file save won't cause it now that I am looking at it - so maybe it is my SSD Teensy Drive. I suppose you'll know what the IDE does before T_ports disables Serial?


@KurtE - wondering about the resiliency and independence of the systems [ SPI and _isr and Serial1.print and clock change ] of course I thought of something(s) I did before. RESULTS:: no problem.

Started an IntervalTimer on 2 us schedule - so 500K per second. The _isr just did a jj++, and read kk=micros(); Edited your loop to take out the press 'Any Key' so I wouldn't wear out the 'Any' key and the code free loops.

On loop() Pause a second showing how many increments a var jj got :: IntvTimer jj=1132054

The other thing I have is this fancy 115Kbaud Serial 1 to another Teensy so why not print some - just one or 3 chars every 10 ms, because one should never print during an interrupt.

The Async SPI tests seem to be running without fail and all that happened is the _isr is missing some ticks I suppose with prints not getting done in time:: IntvTimer jj=1129211

BUT WAIT there is more ... Adding printing of TEMP and remembered I can change CPU speed - No problem 800 to 99.4 MHz:
>>> Clock Speed is:804000000 IntvTimer jj=1650329 ms Time=3302 deg C=48.55
>>> Clock Speed is:696000000 IntvTimer jj=1649946 ms Time=3301 deg C=49.86
>>> Clock Speed is:600000000 IntvTimer jj=1652114 ms Time=3306 deg C=49.21
>>> Clock Speed is:498000000 IntvTimer jj=1655092 ms Time=3311 deg C=48.55
>>> Clock Speed is:402000000 IntvTimer jj=1658511 ms Time=3318 deg C=46.59
>>> Clock Speed is:300000000 IntvTimer jj=1667455 ms Time=3336 deg C=45.93
>>> Clock Speed is:201000000 IntvTimer jj=1691451 ms Time=3384 deg C=45.28
>>> Clock Speed is:99428571 IntvTimer jj=1859830 ms Time=3725 deg C=43.32
* note the baseline for jj changed - I was excluding the counts over a delay(1000) - now changed so the ms time and jj should represent 500K/sec timer _isr

_isr code
Code:
IntervalTimer ITtest;     // ITtest.begin( TimeSome, 2);
volatile uint32_t kk,jj = 0;
void TimeSome() {
  jj++;
  kk=micros();
  if ( !(kk %10000) )   Serial1.print("*");
  if ( !(kk %100000) )   Serial1.print("!\n");  // prints :: **********!
}


@KurtE - looking at my Serial# printing under Fault problem (code used posted prior) - is there a reason or way to incorporate a fix for that in the code HardwareSerial? Where the FIFO gets empty but cannot summon an _ISR for normal operation - it would take an extra polling call perhaps a no_ISR_flush( with timeout ) to clear the buffer. As noted - when the buffer fills the current code does force out a char to FIFO to make room in the buffer - but that is not working in the general case to empty the buffer … under Fault. Perhaps the current .flush() code could have the interrupt level check added and when that is the case use code like I did to at least fill the FIFO once each call?
 
I'm not getting a clear picture of what's really happening on your screen from only "the File save isn't shown done for 5 secs or 50 seconds to even start the compile".

Any chance you could record a screencast, so I can watch it happen?
 
@Frank
Went though a couple more examples, without much luck. The only ones that I got working were your example, and guitar. I also changed the clock to 786432000 with a 12Mhz mclk. Also, changed the sampling frequency to 48kHz. Both examples still worked with those settings as well. LRCLK was right on the 48kHz with those settings.
 
@Frank
Went though a couple more examples, without much luck. The only ones that I got working were your example, and guitar. I also changed the clock to 786432000 with a 12Mhz mclk. Also, changed the sampling frequency to 48kHz. Both examples still worked with those settings as well. LRCLK was right on the 48kHz with those settings.

Yes, there is still much work.
There are more files that might have a #if defined (kinetisk)
I'd just change that to #if defined (__ARM_ARCH_7EM__) - this matches all cortex M4 and M7 - and might match some distant future - teensy too.. :)
For some hardware-independend filters or effects, this should work fine.
 
Yes, there is still much work.
There are more files that might have a #if defined (kinetisk)
I'd just change that to #if defined (__ARM_ARCH_7EM__) - this matches all cortex M4 and M7 - and might match some distant future - teensy too.. :)
For some hardware-independend filters or effects, this should work fine.
Understood. Was about to update my post - for the passthroughStereo example I did get an error that I want to put down before I forget: F:\arduino-1.8.8-t4\hardware\teensy\avr\cores\teensy4/AudioStream.h:145: undefined reference to `vtable for AudioInputI2S'.

I was just beginning to go through the changes you made. Will keep an eye on other defines. I did notice when the kinetisk defines - I was just adding the 1052 and 1062, but the __ARM_ARCH_7EM__ would be easier.
 
I'd just change that to #if defined (__ARM_ARCH_7EM__) - this matches all cortex M4 and M7 - and might match some distant future - teensy too..
@Frank
Just did a quick check and to use that define boards.txt would have to be changed for the T4, i.e.,
Code:
teensy4b.build.flags.defs=-D__IMXRT1052__ -DTEENSYDUINO=146 -D__ARM_ARCH_7EM__
If @Paul has no problem adding this it might be simpler it other chips besides the 1062/1052 will be used in the T4.x series :)
 
Don't think so. When I compiled with verbose mode _ARM_ARCH_7EM__ wasn't defined. When I added it to the build flags def then it showed during the compile.

EDIT: Yep; Edit: two underscores. - was just a typo
 
Status
Not open for further replies.
Back
Top