T4.1 Interrupts(?), analogRead, usbMIDI problems

Status
Not open for further replies.

UHF

Well-known member
Hello, sorry if any of this is vague. I can't immediately post all the code to demonstrate this as there is a lot that would need cutting down - I'm just looking for ideas of what the problem(s) may be.

I'm moving my synth code from 3.6 (working fine) to 4.1 and plowing through the problems. The increase in processor speed meant thant the multiplexer code needed 50us delays before each analogRead(..). I'm getting problems with the USB MIDI (MIDI from the client USB on the Teensy), Serial and USB Host MIDI are fine. MUX reading is fine without usbMIDI. My loop() looks like this:

Code:
void loop() {
  myusb.Task();			//USB HOST MIDI Class Compliant
  midi1.read(midiChannel);  	//USB HOST MIDI Class Compliant
//  usbMIDI.read(midiChannel); //USB Client MIDI
  MIDI.read(midiChannel);    	//Serial1 MIDI 5 Pin DIN
  checkMux(); 			//routine to check two 4067 MUXs with analogRead()
  checkSwitches();		//routine to check several switches with digitalReadFast()
  checkEncoder();		//Uses Teensy Encoder lib 
}

I'm using Serial + Audio + MIDI. When usbMIDI is included, I get random digital noise on USB Audio and the sound cuts every 8s for about a second, then continues. Everything is slow to respond. Commenting out the checkMux() stops this problem, but the digital noise persists.

What do you think? Could this be problems with interrupts? Many thanks for your time.

My connections to the Teensy 4.1 are like this (AB_... are connections to the Audio Board):
SCH.jpg
 
Last edited:
Hello, again. I knew you were all on the edge of your seats, reloading the page every five minutes to see if there was any update or solution to this :rolleyes:

I suspected that it might be a memory problem. Compiling the code for a T4.1 on default - Faster gives:
Sketch uses 280080 bytes (3%) of program storage space. Maximum is 8126464 bytes.
Global variables use 390420 bytes (74%) of dynamic memory, leaving 133868 bytes for local variables. Maximum is 524288 bytes.


sometimes works, often locks-up.

Compiling with Smallest Code gives:
Sketch uses 194480 bytes (2%) of program storage space. Maximum is 8126464 bytes.
Global variables use 288020 bytes (54%) of dynamic memory, leaving 236268 bytes for local variables. Maximum is 524288 bytes.


and it works fine without noise or lock-ups. So I can assume I'm running out of memory? I tried using heapfree() (from T4PowerButton library), which suggested memory was available though. I need to be cutting down on global variables I think.
 
Hi @UHF

Afraid I have no insights on the memory issue but I've also been converting a project from 3.x to 4.x and your analogRead and Mux issues triggered me.

After going round in circles for ages with erratic behaviour I also had to add delay to the mux checking routine for the pots where I didn't in the past.

I don't like having delays in the code and have now been able to remove them by removing the small capacitor I had across the pot. I can't see a schematic for your synth but looks like you have small caps across ground and the pots which I aways thought was good practice but doesn't play well when you are quickly switching between them using a mux. I've removed them and I'm using ResponsiveAnalogRead and much happier with the results.

May or may not help but thought I'd share anyway....Cheers Paul
 
Again sort of hard to say with all of the information we don't have :D

Actually I was looking every 10 minutes ;)

memory space... Again depends on what all you are doing.

But for example if you have some big global arrays that are not initialized you can move those to the other part of memory.

Remember the T4.x have 1MB of memory split into two 512Kb parts. Which your total is talking about.

So for example if you have a large array, you can declare it DMAMEM and it will be allocated in the other 512kb block of memory. Likewise using malloc (new) allocates memory out of here as well.

Also if you have static tables, that don't change, you can keep them in flash by defining them as PROGMEM.

Also with the T4.x boards are different is that both the code space and the data space use up the 512KB. That is the real memory is divided into 16 32kb chunks. So chunks of memory is first reserved for code.

So if my math is correct your code: 280080 maybe take 9 of these pages (depending). So that leaves 7 pages for memory which won't fit...,

But again my math may be off..

What do you do about this? Again get as much Code and Data out of this area.

To get code not to be downloaded into these sections of memory, you do that by marking funcsiont and like as being FLASHMEM.

Examples in the core like:
Code:
FLASHMEM void putchar_debug(char c)
{
	while (!(LPUART3_STAT & LPUART_STAT_TDRE)) ; // wait
	LPUART3_DATA = c;
}

FLASHMEM void printf_debug_init(void)
{
        CCM_CCGR0 |= CCM_CCGR0_LPUART3(CCM_CCGR_ON); // turn on Serial4
        IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06 = 2; // Arduino pin 17
        LPUART3_BAUD = LPUART_BAUD_OSR(25) | LPUART_BAUD_SBR(8); // ~115200 baud
        LPUART3_CTRL = LPUART_CTRL_TE;
}

There is more details about memory sections in the thread I started: https://forum.pjrc.com/threads/57326-T4-0-Memory-trying-to-make-sense-of-the-different-regions
Plus Paul has put up some of these details up on the product page: https://www.pjrc.com/store/teensy40.html

The thread I mention has a tool that @FrankB started off, and I updated for own needs. It currently has not been updated for T4.1... maybe I will play with it again and add it back to my platform.txt file to see the data as part of my build.

Hope that helps some
 
The increase in processor speed meant thant the multiplexer code needed 50us delays before each analogRead(..).
Why waste the extra speed waiting for you MUX to settle.. set them for the next read right after the last and then go do other things... by the time you go to read it will have settled.

Alternately don't set/read on every loop and include an elllapsedMicros to limit the delays
 
Last edited:
Thanks for the replies and ideas. I'll start looking into optimising memory next.

By the way, I've taken the delays out of the Mux ADC reading code. Before, I needed a varying amount of time to get reliable readings, up to 200us. But now, they're not needed and reads are very stable, the same as on the T3.6 PCB. It's a 4067 mux. I can only think that the lack of memory meant that the processor needed time to allocate more memory for reads? Is that reasonable (and how it works?)
 
Hi UHF, I use the same mux and had similar periods of stability. I'd come back to it the next day and it would be erratic again needing long settle times.

I thought it might be temperature related, then i thought it was ext. noise related - was driving me crazy.

In the end it was the capacitors on the pots (they take time to charge) and removing them gave reliable results. On its own the mux settle really quickly (nanoseconds).

Don't know if any of this applies but just incase you wake up tomorrow and it is off again.

Good advice from oddson above on putting some sort of timer in the loop - with the speed of T4 you must be scanning the pots at a really high rate every loop

cheers, Paul
 
Again follow on to my previous post (#4). I added back my (originally pilfered from @FrankB) that prints out more complete build memory information than the build does.
Found I needed to update the code/exe I had for T4.1. Also new builds appear to want \n instead of \r for line breaks, so made that change. Plus put in more descriptive
text for showing the breakdown of which chunks are used for code versus data.

I used the instructions from the posting: https://forum.pjrc.com/threads/5732...ferent-regions?p=213345&viewfull=1#post213345

Example partial output from a build this morning
Code:
\cmd /c "C:\\arduino-1.8.13\\hardware\\teensy\\..\\tools\\arm\\bin\\arm-none-eabi-gcc-nm -n C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_998054\\JoystickBT.ino.elf | D:\\GITHUB\\imxrt-size\\Debug\\imxrt-size.exe"

FlexRAM section ITCM+DTCM = 512 KB
    Config : aaaaaaaf (DDDDDDDDDDDDDDII)
    ITCM :  65224 B	(99.52% of   64 KB)
    [COLOR="#FF0000"]DTCM :  41664 B	( 9.08% of  448 KB)
    Available for Stack: 417088[/COLOR]
OCRAM: 512KB
    DMAMEM:  12384 B	( 2.36% of  512 KB)
    Available for Heap: 511904 B	(97.64% of  512 KB)
Flash:  88808 B	( 1.09% of 7936 KB)
Using library USBHost_t36 at version 0.1 in folder: C:\Users\kurte\Documents\Arduino\libraries\USBHost_t36 
"C:\\arduino-1.8.13\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-size" -A "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_998054/JoystickBT.ino.elf"
Sketch uses 88800 bytes (1%) of program storage space. Maximum is 8126464 bytes.
[COLOR="#008000"]Global variables use 107188 bytes (20%) of dynamic memory, leaving 417100 bytes for local variables. Maximum is 524288 bytes.[/COLOR]

The important differences is understanding that your data does NOT actually have a maximum size of 512KB it only has those chunks of the 512KB that are left after the code size that is downloaded into ITCM rounded up to 32kb chunks, so in my case here I have 448KB not 512KB

Also note, the post process program will error out if it detects that DTCM+ITCM won't fit.


Note: @frankB I believe has a library that can print out similar data at the start of a run. I don't remember it's location. I know it was mentioned in the thread I linked to.
 
Status
Not open for further replies.
Back
Top