Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Active MTP seems to interfere with SD writing #41

Open
h4yn0nnym0u5e opened this issue Oct 30, 2022 · 4 comments
Open

Active MTP seems to interfere with SD writing #41

h4yn0nnym0u5e opened this issue Oct 30, 2022 · 4 comments

Comments

@h4yn0nnym0u5e
Copy link

As noted in this post and following, there seem to be issues when attempting to write to an SD card when it is visible (to Windows 10 64-bit, in my test case). This seems to be way worse when the SD card is in a Teensy 4.1 built-in slot using SD.begin(BUILTIN_SDCARD). The result is failed writes, after what looks like a 1 second timeout. I'm not 100% sure if there are issues when the audio adaptor's SD card slot is used.

In another project I encountered a very similar issue when an SD card was accessed both by foreground and interrupt code - this could be related, or not ...

Either way, the audio guestbook seems to be a good test-bed. My branch here provides a simple way to switch MTP on and off at run-time, along with an (optional) instrumented SD write which can help tell you whether things are going haywire.

Of course, it could be that MTP use requires the sketch to initialise SD access in a specific way in order to co-exist nicely, but if that's the case I couldn't immediately see any documentation, e.g. in bold text in the README!

@KurtE
Copy link
Owner

KurtE commented Nov 1, 2022

Sorry, I am not sure if I understand how the issue is manifesting and/or what steps are involved.
Maybe: @PaulStoffregen or @mjs513 and others - may have other ideas as well.

There are several things mentioned here as well as on the thread, including:
a) Issues with Audio and built in SD Card
b) delays in SD operations
c) failure in SD operations

For now, I am going to ignore Audio - as that is completely external to this. Yes, they do impact each other, but hopefully, that is something to address external from this.

As for concurrent access of multiple portions of code trying to access the SD card at the same time (like interrupt and foreground), again that is external from the MTP stuff. More to do with how to support concurrent access and the like without other things like threading and the like.

So the question would be: what if anything are you doing with MTP, when this issue manifests itself? That is do you simply have MTP enabled? Have a window open on the PC showing the MTP stuff? Are you viewing/browsing the SD on the PC?
Are you uploading/downloading files?

So I will discuss two parts of this:

a) you are doing something like uploading/downloading file - Then the code will currently hang in there and wait for the file to be transfer and there are interesting timing issues with MTP where if the teensy does not pace itself in a way that the PC is happy it might drop or fail... And if you are waiting to do writes to another file during this time frame, yes there could be long waits.

I know at some point Paul wants or wanted to, rewrite some up the upload download code to not wait on MTP, but instead have it instead only process only one buffer at a time... At some point we will probably get there or through handling everything through interrupts and state model or less likely through adding some form of threading.

b) you are not doing anything directly with MTP. In this case, other than maybe some initial startup stuff, where maybe the PC does a few queries, to maybe fill in top level what is there and likewise some initial stuff when we add the drive to storage, we ask the drive how big it is and how much space is left (or used). After that, unless you do something directly, the PC probably is not asking for anything.

HOWEVER: in the current MTP stuff, there is one extra thing we try to do with SD drives. That is we try to see if they have media in them or not. And if that changes, we then let the host know of the state change.

This code is only called when you call MTP.loop(); And then it will not call this code more than by default every 500ms (half second).

Now if this is involved in your issue. I believe I put a way in to disable it.
Something like: MTP.storage()->set_DeltaDeviceCheckTimeMS(-1);
Note: Typed on fly might be wrong syntax...

But might be easy test for you try to see if that makes any impact on your issue.

Sorry I know I am just throwing darts here!

@mjs513
Copy link
Collaborator

mjs513 commented Nov 1, 2022

As Kurt mentioned I can't address issues with Audio and SD Card the way you are using it. I can tell you if you look at the datalogging examples you will notice that we writing or reading data to SD card directly we do not call mtp.loop(). As Kurt said it will cause conflicts. Even with the original MTP library this was the way it was handled.

Kurt's suggestion of disabling mtp.loop and then reenabling it should help in some instances.

@h4yn0nnym0u5e
Copy link
Author

So the question would be: what if anything are you doing with MTP, when this issue manifests itself? That is do you simply have MTP enabled? Have a window open on the PC showing the MTP stuff? Are you viewing/browsing the SD on the PC? Are you uploading/downloading files?

Just a window open in Windows File Explorer - I haven't tested to see whether there's a difference if that Explorer instance is "looking at" the MTP disk or not.

So I will discuss two parts of this:

a) you are doing something like uploading/downloading file - Then the code will currently hang in there and wait for the file to be transfer and there are interesting timing issues with MTP where if the teensy does not pace itself in a way that the PC is happy it might drop or fail... And if you are waiting to do writes to another file during this time frame, yes there could be long waits.

No, not up/downloading, so it's...

b) you are not doing anything directly with MTP. In this case, other than maybe some initial startup stuff, where maybe the PC does a few queries, to maybe fill in top level what is there and likewise some initial stuff when we add the drive to storage, we ask the drive how big it is and how much space is left (or used). After that, unless you do something directly, the PC probably is not asking for anything.

... "probably".

HOWEVER: in the current MTP stuff, there is one extra thing we try to do with SD drives. That is we try to see if they have media in them or not. And if that changes, we then let the host know of the state change.

This code is only called when you call MTP.loop(); And then it will not call this code more than by default every 500ms (half second).

Now if this is involved in your issue. I believe I put a way in to disable it. Something like: MTP.storage()->set_DeltaDeviceCheckTimeMS(-1); Note: Typed on fly might be wrong syntax...

But might be easy test for you try to see if that makes any impact on your issue.

Sorry I know I am just throwing darts here!

Darts are good, much better than mud!

I'll have a look at disabling it, either by not calling MTP.loop() while SD write is in progress as @mjs513 suggests, or your "something like" - should be easy enough to figure out what's correct from that clue. The comment next to MTP.loop() in the source said "//This is mandatory to be placed in the loop code.", but I've no idea where that originated - by now I reckon the code's about third-hand and a bit grubby. But I was leery of just not calling it, given that comment.

The original code does frequent calls to MTP.loop() interleaved with SD writes (every 5.8ms up to 93ms, depending on configuration). I've (possibly wrongly) assumed the SD writes will block until complete, so a subsequent call to MTP.loop() ought to be benign. But maybe not - looking at a couple of logger examples, they have a "delay(100); // run at a reasonable not-too-fast speed for testing" at the end of logData(), so they may well not expose the issue.

The fact that the source of the data is audio is almost certainly entirely irrelevant, apart from the fact that if we can't write at a pretty leisurely 88kB/s then we end up with corrupt audio, and if the SD library disables interrupts (as it sometimes seems to) then it's academic what write speed we can achieve. The latter aspect is definitely nothing to do with MTP!

@h4yn0nnym0u5e
Copy link
Author

Interim report:

  • MTP.storage()->set_DeltaDeviceCheckTimeMS((uint32_t) -1); does indeed fix the issue
  • the issue is only apparent when using the Teensy 4.1 built-in card slot...
  • ...which doesn't seem to interfere with audio interrupts, leading me to think...
  • ...is it using DMA and/or interrupts...
  • ...so the medium change check should be checking for a "transaction in progress" before doing its thing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants