SD.mediaPresent(), MTP, Audio issues.

KurtE

Senior Member+
I thought I would create a new thread specifically on this, as to not have it buried in another somewhat not related topic.

As was reported in the thread: https://forum.pjrc.com/threads/70553-Teensy-4-0-based-Audio-Guestbook?p=315003&viewfull=1#post315003
And more recently in an issue against the MTP_Teensy github project: https://github.com/KurtE/MTP_Teensy/issues/41

Short form: The problem reported in the above issue, has to do with if you enable MTP in the Audio Guestbook, writes to the SD card slow down a lot and in addition to this, there are some Audio output issues.

We have isolated this down to, the fact that the current MTP code, will be default try to determine if there is an SDCard within an SD drive, on a periodic basis.
Currently I believe it defaults to every half second. Or more specifically to the next call to MTP.loop(), when there has elapsed at least a half second from the previous call.

And the behavior issue appears to be far more pronounced on the T3.6 or 4.x when using a BUILT in card.

All of this code then boils down to us, calling: SD.mediaPresent(). actually, we call it with a pointer to each specific instance of the SDClass that was added to the MTP list.

Note: there are a few different ways to disable this code: The one that has been tested in the issue mentioned above:
Code:
MTP.storage()->set_DeltaDeviceCheckTimeMS((uint32_t) -1);

You can also with this version explicitly add the SD volume and say it is an unknown filesystem type to have not register for this.
Something like: MTP.addFilesystem(&SD, "SD", MTP_FSTYPE_UNKNOWN);

Also, you have the option, of not calling MTP.loop() if you are in the middle of something time critical.

Next up what is mediaPresent() doing?
Will post that on the next message.
 
Last edited:
The SD code for detecting this is:
Code:
bool SDClass::mediaPresent()
{
	//Serial.print("mediaPresent: ");
	bool ret;
	SdCard *card = sdfs.card();
//	Serial.printf("mediaPresent: card:%x cs:%u cd:%u\n", (uint32_t)card, csPin_, cdPin_);
	if (card) {
		if (cardPreviouslyPresent) {
	[COLOR="#FF0000"]		#ifdef BUILTIN_SDCARD
			uint32_t s;
			if (csPin_ == BUILTIN_SDCARD) {
				#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
				card->syncDevice();
				#endif  // defined(__MK64FX512__) || defined(__MK66FX1M0__)
				s = card->status();
			} else s = 0xFFFFFFFF;
			#else
			const uint32_t s = 0xFFFFFFFF;
			#endif
[/COLOR]			if (s == 0xFFFFFFFF) {
				// see if we have digital pin to bypass...
				if (cdPin_ < NUM_DIGITAL_PINS) ret = digitalRead(cdPin_);
				else {
					// SPI doesn't have 32 bit status, read CID register
					cid_t cid;
					ret = card->readCID(&cid);
				}
				//Serial.print(ret ? "CID=ok" : "CID=unreadable");
			} else if (s == 0) {
				// assume zero status means card removed
				// bits 12:9 are card state, which should
				// normally be 101 = data transfer mode
				//Serial.print("status=offline");
				ret = false;
				#ifdef _SD_DAT3
				if (csPin_ == BUILTIN_SDCARD) 
					pinMode(_SD_DAT3, INPUT_PULLDOWN);
				#endif
			} else {
				//Serial.print("status=present");
				ret = true;
			}
		} else {
			// TODO: need a quick test, only call begin if likely present
			ret = true; // assume we need to check

			#ifdef _SD_DAT3
			if (csPin_ == BUILTIN_SDCARD) ret = digitalReadFast(_SD_DAT3);
			else
			#endif
			{
				if (cdPin_ < NUM_DIGITAL_PINS) ret = digitalRead(cdPin_);
			}
			// now try to restart
			if (ret)
			{
				ret = sdfs.restart();
				// bugbug:: if it fails and builtin may need to start pinMode again...
			}
			//Serial.print(ret ? "begin ok" : "begin nope");
		}
	} else {
		//Serial.print("no card");
		ret = false;
	}
	//Serial.println();
	cardPreviouslyPresent = ret;
	return ret;
}
Hopefully the code specific to BUILTIN_SDCARD is in red. Note: I only changed the color for the part where we believe that we have an SDCard. That is either when we first
opened up the drive or when the last time we called this.

@PaulStoffregen - was wondering why in the case of T3.5/6 we call syncDevice but not on T4.x? I am assuming this is not that we were doing this before T4.x, as we already checked that BUILTIN_SDCARD is defined.

In the case of T3.5/6 when we call SyncDevice and one or more files are open and have dirty buffers. I am trying to remember if this will cause the SD code to flush out all of these?
If so, that could be one timing issue.

So next up to see what card->status() does. More specifically how long does it take, does it disable interrupts...

And see if it returns something or if we end up needing to call Card->readCID()

In the case of Built-in I know it won't take the digitalRead short cut to find out, this is only for other drives where the caller has registered a chip detect pin. However in the case that the SD card did not exist before, we can detect this with the SD_DAT3 pin, which we see in the other part.

And then assuming that any of these operations are expensive, see if we can logically bypass it, without throwing it out with the bathwater.

For example, if we could detect if the user code has read or wrote to any files during the timeout period, bypass this code...

Now back to playing (some here and some elsewhere)
 
As I opened this particular can of worms ... here's a fairly minimal example to reproduce the issue. It repeatedly writes a 2Mb file in 4kB chunks (so 512 writes), and reports any write that took over 1000µs - you may need to change that threshold for your particular SD card, or if you switch over to using the audio adaptor slot rather than the one on the Teensy 4.1.

Code:
#include <SD.h>
#include <TimeLib.h>
#include <MTP_Teensy.h>

#define SDCARD_CS_PIN    BUILTIN_SDCARD //10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14


const char* junk = "abcdefghijklmnopqrstuvwxyz123456";
char buffer[4096];
void setup() 
{
  // Initialise the SD card
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  while (!(SD.begin(SDCARD_CS_PIN))) 
  {
    Serial.println("Unable to access the SD card");
    delay(500);
  }

  // Initialise MTP
  MTP.begin();
  MTP.addFilesystem(SD, "SD Card");

  // fill buffer
  int sl = strlen(junk);
  char* p;
  for (p=buffer; (p+sl) < (buffer+sizeof buffer); p+=sl)
    memcpy(p,junk,sl);
  memcpy(p,junk,buffer+sizeof buffer-p);
}


int written;
File f;

void loop() 
{
  uint32_t t = micros();
  
  if (0 == written)
  {
    Serial.println("Opening...");
    f = SD.open("junk.txt",FILE_WRITE);
    f.truncate();
  }
  if (f)
    written += f.write(buffer,sizeof buffer);
  t = micros() - t;
  MTP.loop(); 

  if (t > 1000)
    Serial.printf("Time to write: %luus\n", t);
  
  if (written > 2048*1024)
  {
    f.close();
    written=0;
    delay(1000);
  }
}
 
Thanks @h4yn0nnym0u5e

I am going to simplify some of this sketch to remove some complexity of other libraries.
Also unclear what board you wrote this for as the setSCK and setMOSI feel more for T3.6 or so...

Here is a quick and dirty:
Code:
#include <SD.h>
//#include <TimeLib.h>
//#include <MTP_Teensy.h>

#define SDCARD_CS_PIN    BUILTIN_SDCARD //10
//#define SDCARD_MOSI_PIN  7
//#define SDCARD_SCK_PIN   14


const char* junk = "abcdefghijklmnopqrstuvwxyz123456";
char buffer[4096];
void setup() 
{
  // Initialise the SD card
  //SPI.setMOSI(SDCARD_MOSI_PIN);
  //SPI.setSCK(SDCARD_SCK_PIN);
  pinMode(13, OUTPUT);
  while (!(SD.begin(SDCARD_CS_PIN))) 
  {
    Serial.println("Unable to access the SD card");
    delay(500);
  }

  // fill buffer
  int sl = strlen(junk);
  char* p;
  for (p=buffer; (p+sl) < (buffer+sizeof buffer); p+=sl)
    memcpy(p,junk,sl);
  memcpy(p,junk,buffer+sizeof buffer-p);
}


int written;
File f;
elapsedMicros emuTotal;
elapsedMillis emmCheckSD;
uint32_t loop_count = 0;
bool check_media = false;

void loop() 
{
  if (0 == written)
  {
    f = SD.open("junk.txt",FILE_WRITE_BEGIN);
    f.truncate();
    //emmCheckSD = 0;
    emuTotal = 0;
    loop_count = 0;
    
  }
  if (f)
    written += f.write(buffer,sizeof buffer);
  loop_count++;
  
  if (check_media && emmCheckSD > 500) {
    if (!SD.mediaPresent()) Serial.println("Media removed");
    digitalToggleFast(13);
    emmCheckSD = 0;
  }
  
  if (written > 2048*1024)
  {
    f.close();
    Serial.printf("Time to write file: %u loops: %u check:%u\n", (uint32_t)emuTotal, loop_count, check_media);
    written=0;
    delay(5000);
    if (Serial.available()) {
      while (Serial.read() != -1);
      Serial.println("Paused hit any key to continue (c will toggle checking media");
      int ch;
      while ((ch = Serial.read()) == -1);
      if (ch == 'c') check_media = !check_media;
      while (Serial.read() != -1);
    }
  }
}

I am not seeing much change in timings so far with this on T4.1
But it is only calling it maybe on average once maybe twice per file write...

Code:
Time to write file: 104426 loops: 513 check:1
Time to write file: 104321 loops: 513 check:1
Time to write file: 104104 loops: 513 check:1
Time to write file: 104015 loops: 513 check:1
Time to write file: 116145 loops: 513 check:1
Time to write file: 105018 loops: 513 check:1
Time to write file: 105156 loops: 513 check:1
Time to write file: 105190 loops: 513 check:1
Time to write file: 105267 loops: 513 check:1
Time to write file: 105266 loops: 513 check:1
Time to write file: 105357 loops: 513 check:1
Time to write file: 105472 loops: 513 check:1
Time to write file: 105476 loops: 513 check:1
Time to write file: 105524 loops: 513 check:1
Time to write file: 105718 loops: 513 check:1
Time to write file: 105343 loops: 513 check:1
Time to write file: 105414 loops: 513 check:1
Time to write file: 111804 loops: 513 check:1
Time to write file: 106352 loops: 513 check:1
Time to write file: 106233 loops: 513 check:1
Time to write file: 106374 loops: 513 check:1
Paused hit any key to continue (c will toggle checking media
Time to write file: 106406 loops: 513 check:0
Time to write file: 106206 loops: 513 check:0
Time to write file: 106307 loops: 513 check:0
Time to write file: 106387 loops: 513 check:0
But again this is running on T4.1 with builtin.

More tomorrow.
 
Thanks for looking into this!

If you run my code, do you see the occasional super-long write? For me, using BUILTIN_SDCARD, they take just over one second, but it appears your code doesn't reproduce the issue...

I wrote the code for Teensy 4.1 + audio adaptor - the setSCK and setMOSI are only effective if SDCARD_CS_PIN is set to 10, in which case you're testing the audio adaptor's SD card slot. I think the issue is only occurring for BUILTIN_SDCARD, but as the original issues were found on a Teensy 4.0 + audio adaptor I wanted to be able to switch back and forth quickly.
 
I updated your test, to again try to localize what is going on. Theory was that the calls to check the state of the media as maybe to blame.
So far it is not showing up in obvious way with T4.1 built in.

I changed the sketch slightly today, to write the file 16 times bigger. if (written > 2048*1024*16)

And not showing up anything obvious differences in speed:
Code:
Time to write file: 1582758 loops: 8193 check:0
Time to write file: 1583607 loops: 8193 check:0
Time to write file: 1584641 loops: 8193 check:0
Time to write file: 1584984 loops: 8193 check:0
Time to write file: 1583280 loops: 8193 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 1582235 loops: 8193 check:1
Time to write file: 1584823 loops: 8193 check:1
Time to write file: 1585945 loops: 8193 check:1
Time to write file: 1585543 loops: 8193 check:1
Time to write file: 1591495 loops: 8193 check:1
Paused hit any key to continue (c will toggle checking media
I wrote the code for Teensy 4.1 + audio adaptor - the setSCK and setMOSI are only effective if SDCARD_CS_PIN is set to 10, in which case you're testing the audio adaptor's SD card slot. I think the issue is only occurring for BUILTIN_SDCARD, but as the original issues were found on a Teensy 4.0 + audio adaptor I wanted to be able to switch back and forth quickly.
The thing that is confusing about your sketch, is you say running on T4.1, but the setMOSI and setSCK are not valid of T4.x, they are only for T3.x as seen on the Audio page:
Screenshot.png
@Paul - if you look at this page, suggestion, you might want to update the table, on the T3.x to show the CS pin first on the two sub-devices, like you do for the T4.x. I highlighted
what I mean.

Will try now with SPI with the pin 10 to see if anything pops up.
 
Quick update: I tried also on pin 10...
Changed the blink pin to pin 24 so as not to interfere.

Code:
Time to write file: 19371942 loops: 8193 check:0
Time to write file: 19338296 loops: 8193 check:0
Time to write file: 19397856 loops: 8193 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 19411329 loops: 8193 check:1
Time to write file: 19350826 loops: 8193 check:1
Time to write file: 19344316 loops: 8193 check:1
Time to write file: 19259958 loops: 8193 check:1
Paused hit any key to continue (c will toggle checking media
Time to write file: 19397235 loops: 8193 check:0
Time to write file: 19415469 loops: 8193 check:0
Time to write file: 19275515 loops: 8193 check:0
Paused hit any key to continue (c will toggle checking media

Noting jumping out
 
@KurtE
Just tried your sketch on a T4.1 with the BUILTIN_SDCARD. Ran it with and without MTP running:

Without MTP it does look like it periodically jumps in the time to write but nothing over 300000us.
Code:
Time to write file: 361294 loops: 513 check:0
Time to write file: 101988 loops: 513 check:0
Time to write file: 393980 loops: 513 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 101959 loops: 513 check:1
Time to write file: 324030 loops: 513 check:1
Time to write file: 101625 loops: 513 check:1
Time to write file: 159302 loops: 513 check:1
Time to write file: 101783 loops: 513 check:1
Time to write file: 110473 loops: 513 check:1
Time to write file: 112038 loops: 513 check:1
Paused hit any key to continue (c will toggle checking media
Time to write file: 101955 loops: 513 check:0
Time to write file: 110904 loops: 513 check:0
Time to write file: 101562 loops: 513 check:0
Time to write file: 110420 loops: 513 check:0
Time to write file: 101819 loops: 513 check:0
Time to write file: 322836 loops: 513 check:0
Time to write file: 116761 loops: 513 check:0
Time to write file: 191392 loops: 513 check:0
Time to write file: 148633 loops: 513 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 220504 loops: 513 check:1
Time to write file: 185272 loops: 513 check:1
Time to write file: 110073 loops: 513 check:1
Time to write file: 102212 loops: 513 check:1
Time to write file: 110093 loops: 513 check:1
Time to write file: 102042 loops: 513 check:1
Time to write file: 110313 loops: 513 check:1
Time to write file: 102751 loops: 513 check:1
Time to write file: 111994 loops: 513 check:1
Time to write file: 102241 loops: 513 check:1
Time to write file: 109696 loops: 513 check:1
Time to write file: 102601 loops: 513 check:1
Time to write file: 230927 loops: 513 check:1
Time to write file: 137094 loops: 513 check:1

If I put MTP in the sketch - times increase dramatically:
Code:
Time to write file: 1522100 loops: 514 check:0
Time to write file: 1529094 loops: 514 check:0
Time to write file: 1522023 loops: 514 check:0
Time to write file: 1530798 loops: 514 check:0
Time to write file: 1522673 loops: 514 check:0
Time to write file: 1530778 loops: 514 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 1523306 loops: 514 check:1
Time to write file: 1530557 loops: 514 check:1
Time to write file: 1522138 loops: 514 check:1
Time to write file: 1530449 loops: 514 check:1
Time to write file: 1521033 loops: 514 check:1
Time to write file: 1758602 loops: 514 check:1
Time to write file: 1527110 loops: 514 check:1
Time to write file: 1530178 loops: 514 check:1
Time to write file: 1522048 loops: 514 check:1
 
Thanks @mjs513 -
I was adding that as well:

Speeds without MTP
Code:
Time to write file: 1579133 loops: 8193 check:0
Time to write file: 1580317 loops: 8193 check:0
Time to write file: 1582681 loops: 8193 check:0
Time to write file: 1582808 loops: 8193 check:0
Time to write file: 1577934 loops: 8193 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 1583336 loops: 8193 check:1
Time to write file: 1583178 loops: 8193 check:1
Time to write file: 1582841 loops: 8193 check:1
Time to write file: 1583766 loops: 8193 check:1
Time to write file: 1582506 loops: 8193 check:1
Paused hit any key to continue (c will toggle checking media

With MTP... including SD built in and testing
Code:
Time to write file: 23160072 loops: 8208 check:0
Time to write file: 24218728 loops: 8209 check:0
Time to write file: 24219580 loops: 8209 check:0
Time to write file: 24218743 loops: 8209 check:0
Time to write file: 24218745 loops: 8209 check:0

With MTP, but SD told to MTP as not SD
Code:
Time to write file: 8204798 loops: 8193 check:0
Time to write file: 8209268 loops: 8193 check:0
Time to write file: 8204853 loops: 8193 check:0
Time to write file: 8204801 loops: 8193 check:0

Tried with MTP and Littlefs_program disk added but NOT SD:
Code:
Time to write file: 8203559 loops: 8193 check:0
Time to write file: 8202776 loops: 8193 check:0
Time to write file: 8202776 loops: 8193 check:0
Time to write file: 8215834 loops: 8193 check:0
Time to write file: 8201742 loops: 8193 check:0
Time to write file: 8201746 loops: 8193 check:0
Which is right in line with SD added so MTP.loop() calls appeared to increase the timing to write the file from about 1.6 seconds to about 8.2 seconds
and the checking of the SD.mediaPresent jumped it to 24 seconds but calling directly in sketch did not impact much. Strange!

I am also curious on the MTP where it is checking it was taking more passed through 8209 versus 8193? So some writes failed would be my assumption.
Will double check. And put tests in to see.
 
I now understand the first uptick in time to the 8 second range.

I now have it running with MTP with both the SD card and program disk but not checking SD status and timings are better again:
Code:
Time to write file: 1581170 loops: 8193 check:0
Time to write file: 1581625 loops: 8193 check:0
Time to write file: 1597876 loops: 8193 check:0
Time to write file: 1582096 loops: 8193 check:0
Time to write file: 1581698 loops: 8193 check:0
Time to write file: 1582150 loops: 8193 check:0
Time to write file: 1585469 loops: 8193 check:0
Time to write file: 1581566 loops: 8193 check:0
Screenshot.png

The problem is in core (usb_mtp.c)
Code:
int usb_mtp_recv(void *buffer, uint32_t timeout)
{
	uint32_t wait_begin_at = systick_millis_count;
	uint32_t tail = rx_tail;
	while (1) {
		if (!usb_configuration) return -1; // usb not enumerated by host
		if (tail != rx_head) break;
		[COLOR="#FF0000"]if (timeout == 0) return 0;[/COLOR]
		if (systick_millis_count - wait_begin_at > timeout)  {
			return 0;
		}
		yield();
	}
	if (++tail > RX_NUM) tail = 0;
	uint32_t i = rx_list[tail];
	int len = rx_list_transfer_len[tail];
	rx_tail = tail;

	uint8_t *rx_item_buffer = rx_buffer + i * MTP_RX_SIZE_480;
	// BUGBUG Should we use the 
	memcpy(buffer,  rx_item_buffer, len);
	rx_queue_transfer(i);
	//memset(rx_transfer, 0, sizeof(rx_transfer));
	//usb_prepare_transfer(rx_transfer + 0, rx_buffer, rx_packet_size, 0);
	//usb_receive(MTP_RX_ENDPOINT, rx_transfer + 0);
	return len;
}

I added the line in RED. without it, it would wait for the systick_millis_count to change before returning.
I will make change in core and do PR, may do simpler change of: if (systick_millis_count - wait_begin_at >= timeout)

But if want, give it a try before, I create a PR, and it is pulled in and a new beta build...

EDIT: PR: https://github.com/PaulStoffregen/cores/pull/663
 
Last edited:
Actually, it appears like this fixed the issue with checking the SD card as well for the timing.

Code:
Time to write file: 1585144 loops: 8193 check:0
Time to write file: 1584304 loops: 8193 check:0
Time to write file: 1585216 loops: 8193 check:0
Time to write file: 1583528 loops: 8193 check:0
Time to write file: 1585150 loops: 8193 check:0
Time to write file: 1590066 loops: 8193 check:0
Time to write file: 1585189 loops: 8193 check:0
SD Disk SD Card(0) removed dt:3
SD Disk SD Card(0) inserted dt:149344
Time to write file: 1602179 loops: 8193 check:0
Time to write file: 1582795 loops: 8193 check:0
Time to write file: 1599725 loops: 8193 check:0
This is with MTP now checking the state of the SD Card every half second or so.
Back to around 1.6 seconds for writing the file.

Current version of program:
Code:
#include <SD.h>
#if defined(USB_MTPDISK) || defined(USB_MTPDISK_SERIAL)
// If user selected a USB type that includes MTP, then set it up
#include <MTP_Teensy.h>
#include <LittleFS.h>
LittleFS_Program    progdisk;
#endif


//#include <TimeLib.h>
//#include <MTP_Teensy.h>

#define SDCARD_CS_PIN    BUILTIN_SDCARD //10
//#define SDCARD_CS_PIN    10
#define BLINK_PIN 24
//#define SDCARD_MOSI_PIN  7
//#define SDCARD_SCK_PIN   14


const char* junk = "abcdefghijklmnopqrstuvwxyz123456";
char buffer[4096];
void setup() 
{
  // Initialise the SD card
  //SPI.setMOSI(SDCARD_MOSI_PIN);
  //SPI.setSCK(SDCARD_SCK_PIN);
  while (!Serial && millis() < 3000);
  Serial.println("\n *** Start SD Timing test ***");
  pinMode(BLINK_PIN, OUTPUT);
  while (!(SD.begin(SDCARD_CS_PIN))) 
  {
    Serial.println("Unable to access the SD card");
    delay(500);
  }

#ifdef MTP_TEENSY_H
  MTP.begin();
  MTP.addFilesystem(SD, "SD Card"/*, MTP_FSTYPE_UNKNOWN*/);
   uint32_t  disk_size = (1024*1024);
   progdisk.begin(disk_size);   // minimum program disk size is 256k.
   MTP.addFilesystem(progdisk, "progdisk");

#endif
  // fill buffer
  int sl = strlen(junk);
  char* p;
  for (p=buffer; (p+sl) < (buffer+sizeof buffer); p+=sl)
    memcpy(p,junk,sl);
  memcpy(p,junk,buffer+sizeof buffer-p);
}


int written;
File f;
elapsedMicros emuTotal;
elapsedMillis emmCheckSD;
uint32_t loop_count = 0;
bool check_media = false;

void loop() 
{
#ifdef MTP_TEENSY_H
  MTP.loop();
#endif  
  if (0 == written)
  {
    f = SD.open("junk.txt",FILE_WRITE_BEGIN);
    f.truncate();
    //emmCheckSD = 0;
    emuTotal = 0;
    loop_count = 0;
    
  }
  if (f)
    written += f.write(buffer,sizeof buffer);
  loop_count++;
  
  if (check_media && emmCheckSD > 500) {
    if (!SD.mediaPresent()) Serial.println("Media removed");
    digitalToggleFast(BLINK_PIN);
    emmCheckSD = 0;
  }
  
  if (written > 2048*1024*16)
  {
    f.close();
    Serial.printf("Time to write file: %u loops: %u check:%u\n", (uint32_t)emuTotal, loop_count, check_media);
    written=0;
    delay(5000);
    if (Serial.available()) {
      while (Serial.read() != -1);
      Serial.println("Paused hit any key to continue (c will toggle checking media");
      int ch;
      while ((ch = Serial.read()) == -1);
      if (ch == 'c') check_media = !check_media;
      while (Serial.read() != -1);
    }
  }
}
 
Running your sketch in post #4 after making the change:
Code:
Time to write file: 110470 loops: 513 check:0
Time to write file: 103019 loops: 513 check:0
Time to write file: 111089 loops: 513 check:0
Time to write file: 102183 loops: 513 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 110846 loops: 513 check:1
Time to write file: 101591 loops: 513 check:1
[COLOR="#FF0000"]Time to write file: 191474 loops: 513 check:1
[/COLOR]Time to write file: 110979 loops: 513 check:1
Time to write file: 103134 loops: 513 check:1
Time to write file: 109741 loops: 513 check:1
Time to write file: 104124 loops: 513 check:1

Notes: The time is read is when i opened up directory in Windows. Also I was able to copy the file down to the PC with any time change.

EDIT. Decided to try one more thing:
Code:
Time to write file: 102461 loops: 513 check:1
SD Disk SD Card(0) removed dt:3
Media removed
SD Disk SD Card(0) inserted dt:3
Time to write file: 204268 loops: 513 check:1
Time to write file: 102124 loops: 513 check:1
Time to write file: 111128 loops: 513 check:1
 
I updated your test, to again try to localize what is going on. Theory was that the calls to check the state of the media as maybe to blame.
So far it is not showing up in obvious way with T4.1 built in.

I changed the sketch slightly today, to write the file 16 times bigger. if (written > 2048*1024*16)

And not showing up anything obvious differences in speed:
Code:
Time to write file: 1582758 loops: 8193 check:0
Time to write file: 1583607 loops: 8193 check:0
Time to write file: 1584641 loops: 8193 check:0
Time to write file: 1584984 loops: 8193 check:0
Time to write file: 1583280 loops: 8193 check:0
Paused hit any key to continue (c will toggle checking media
Time to write file: 1582235 loops: 8193 check:1
Time to write file: 1584823 loops: 8193 check:1
Time to write file: 1585945 loops: 8193 check:1
Time to write file: 1585543 loops: 8193 check:1
Time to write file: 1591495 loops: 8193 check:1
Paused hit any key to continue (c will toggle checking media

The thing that is confusing about your sketch, is you say running on T4.1, but the setMOSI and setSCK are not valid of T4.x, they are only for T3.x as seen on the Audio page:
View attachment 29694
@Paul - if you look at this page, suggestion, you might want to update the table, on the T3.x to show the CS pin first on the two sub-devices, like you do for the T4.x. I highlighted
what I mean.

Will try now with SPI with the pin 10 to see if anything pops up.
My (slightly) bad - I copied "the essentials" from the original sketch, and didn't think to check that the author of those lines (@DD4WH) had picked the correct SPI pins! I don't think it actually makes a difference, and changing SDCARD_CS_PIN does seem to allow one to switch from the built-in to the audio adaptor.

I've tested your one-character change to usb_mtp.c in both my minimal test and the original guestbook sketch, and it does appear to fix the issue.

As an aside ... your "improved" test of the time to write the whole file does NOT show the issue nearly as obviously as my code in post #3 ... it's just a tiny bit de-motivating to follow the Forum Rule, only to have ones example code ignored!
 
Sorry, I actually did start off with your code. And the issue which it showed was that specific writes were taking way too long, which we confirmed. So the forum rules of having the example did help out a lot here!

Also knowing that the example exists added motivation for someone like me, to look at it and understand what is going on.

So, then what I became interested in, was to see if it was cumulative. That is, did one write go real long and the others go short...
Like maybe it forced the dirty buffers to be all written out at that point and as such the next ones went real fast (nope)...

Which caused me to need to drill down and see what was happening. It appeared like the problem was the detecting media present or not. So wanted to test that Independant of MTP. Turned out also wrong assumption. So then added in MTP, and sure enough, times went way up, with just MTP... And went even slower with the testing for SD removed. So added lots more debug about 3 different times, until I localized the main issue here.

So again, I do thank you for taking the time to do the example, as it what led to finding out the root issue. (Or at least one so far)

Kurt
 
Back
Top