notice the sector count?
Looks like it's being printed as a signed 32-bit int when it should be unsigned. -387938129 = 0xE8E088AF = 3,907,029,167 sectors. Multiply by 512 bytes per sector = 2000398933504 bytes which matches the reported capacity.
notice the sector count?
Ok did some testing with MTP (writing/reading files and transferring files) and all worked fine with that change.
Drives tested so far:
1. Crucial MX500 500GB 3D NAND SATA 2.5 Inch Internal SSD, up to 560MB/s - CT500MX500SSD1
2. INDMEM mSATA SSD 256GB Internal Mini SATA III SSD Micro-SATA TLC 3D NAND Flash 256 GB
3. HP SSD S 600 120GB
4. Silicon Power 2TB Rugged Portable External Hard Drive Armor A30:
This was a strange one:
notice the sector count?Code:connected: 1 initialized: 1 USB Vendor ID: 174c USB Product ID: 55aa HUB Number: 0 HUB Port: 0 Device Address: 1 Removable Device: NO VendorID: PHD 3.0 ProductID: Silicon-Power RevisionID: 0 Version: 6 Sector Count:[COLOR="#FF0000"] -387938129[/COLOR] Sector size: 512 Disk Capacity: 2000398933504 Bytes
PS did find adding a delay(500) allowed the drive to come on line
Code:while (!myDrive) { myusb.Task(); } [COLOR="#FF0000"]delay(500)[/COLOR];
Thanks for testing I'll test more of my devices and issue an appropriate PR.
Quick update:
The problem child (SDCZ73-032G-G46) that "works now"
https://www.amazon.com/dp/B01FTQP7ZM?psc=1
I was able to transfer a 6.44mb file to it, but it took probably over a minute to complete.
As compared to an SSD I recently purchased to test...
https://www.amazon.com/gp/product/B095P3ZT2B
which is installed onto:
https://www.amazon.com/gp/product/B07VP2WH73
Which maybe took something like 7 seconds for MTP to transfer to the SSD.
I also tried it with another 8gb stick enfain (USB 2) Probably: https://www.amazon.com/Enfain-Delivering-presentations-Promotional-Distribution/dp/B00HQWLHIE
same file took maybe 15 seconds.
printf("SendObject complete size:%u dt:%u\n", size, (uint32_t)emSendObject);
@KurtE @mjs512 - Decided to just comment out "msReset()" call. Updated my version of USBHost_t36 with @PaulStoffregen version and did a PR for it and extending the timeouts defined in "msc.h".
Glad to see a lot of the problem USB drives are working now Sorry it took so long to discover the problem...
Is it just me or are there major race conditions in ehci.cpp? Lots of list manipulation happening without interrupts disabled and isr() being triggered can easily modify those same lists...
As a basic example, look at USBDriverTimer::Start(). Imagine there's already one active timer, so our timer will be added after it. Instruction flow reaches line 512 and the timer interrupt triggers for the already active timer; when the interrupt handler returns, our timer gets added after the now retired timer and will never be triggered.
NVIC_DISABLE_IRQ(IRQ_USBHS);
txtimer.stop(); // Stop longer timer.
txtimer.start(100); // Start a mimimal timeout
// timer_event(nullptr); // Try calling direct - fails to work
NVIC_ENABLE_IRQ(IRQ_USBHS);
The mass storage code definitely isn't doing anything like that, data transfers are being queued with interrupts enabled which means there is the potential for list corruption (due to the interrupt service routine modifying the lists while they're being updated). I don't think it should be the responsibility of the individual USB device drivers to handle that; the lists are private to the host controller so the proper place would be in ehci.cpp.I understand what you are saying, but at least in many of these cases it may depend on who and how these methods are called. For example if you look in Serial.cpp,
where the txTimer is used.
Whenever we start or stop the timer, there hopefully is code in it like:
So it disables the USB interrupt while it is mucking with the stuff.Code:NVIC_DISABLE_IRQ(IRQ_USBHS); txtimer.stop(); // Stop longer timer. txtimer.start(100); // Start a mimimal timeout // timer_event(nullptr); // Try calling direct - fails to work NVIC_ENABLE_IRQ(IRQ_USBHS);
I believe Paul originally set it up, this way and I then when I was working on Serial, I continued to do it how the earlier code was.
We could use sledgehammer and turn off all interrupts.
But we may not always know the context of how it is going to be called. That is, OK easy to disable all interrupts or specific interrupt, but now always sure it is OK to enable them afterwords. That is the change to the timer may only a part of changing a logical state.
Hope that makes sense
...loads of ReadMe.txt and other text/help files in my Teensy Libraries stored in C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries.however I don't believe Teensyduino installs the readme files for the different libraries it installs.
You are right... For awhile, I did not see ones from some libraries I have worked on... like FlexIO... But it is there now...loads of ReadMe.txt and other text/help files in my Teensy Libraries stored in C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries.
I am still sort of curious on the speed of these drives:
So put an elapsedMillis into the sendObject code, and at the end (debug >= 1)
Code:printf("SendObject complete size:%u dt:%u\n", size, (uint32_t)emSendObject);
First run: Kingston SSD 240gb
SendObject complete size:6754230 dt:5839
Newer 250GB SSD
SendObject complete size:6754230 dt:5096
Old 8 GB Stick:
SendObject complete size:6754230 dt:8429
New 32 GB USB 3 stick:
SendObject complete size:6754230 dt:75461
So like 9 times slower than old stick and like 15 times slower than the SSDs
None of these was running using a HB, the SSDs are running and they have the USB3 connector (blue)
void test_write_file(int ch) {
test_file_write_size = CommandLineReadNextNumber(ch, test_file_write_size);
test_file_size = CommandLineReadNextNumber(ch, test_file_size);
if (ch >= ' ') {
Serial.setTimeout(0);
int cb = Serial.readBytesUntil( '\n', test_file_name, sizeof(test_file_name));
}
File testFile; // Specifes that dataFile is of File type
mscDisk->remove(test_file_name); // try to remove files before as to force it to reallocate the file...
testFile = mscDisk->open(test_file_name, FILE_WRITE_BEGIN);
if (!testFile) {
Serial.printf("Failed to open %s\n", test_file_name);
return;
}
Serial.printf("Start write file: %s length:%u Write Size:%u\n", test_file_name, test_file_size, test_file_write_size);
uint32_t cb_write = test_file_write_size;
uint32_t cb_left = test_file_size;
uint8_t fill_char = '0';
test_file_buffer[cb_write - 2] = '\n'; // make in to text...
elapsedMillis em;
while (cb_left) {
if (cb_left < cb_write) cb_write = cb_left;
memset(test_file_buffer, cb_write - 1, fill_char);
testFile.write(test_file_buffer, cb_write);
fill_char = (fill_char == '9')? '0' : fill_char + 1;
cb_left -= cb_write;
}
testFile.close();
Serial.printf("Time to write: %u\n", (uint32_t)em);
}
Menu Options:
1 - List USB Drives (Step 1)
2 - Select USB Drive for Logging (Step 2)
l - List files on disk
e - Erase files on disk
s - Start Logging data (Restarting logger will append records to existing log)
x - Stop Logging data
d - Dump Log
w [write size] [size] [file name]
r - reset MTP
h - Menu
Start write file: write_test_file.txt length:1048576 Write Size:512
Time to write: 10959
Start write file: write_test_file.txt length:1048576 Write Size:64
Time to write: 10935
Start write file: write_test_file.txt length:1048576 Write Size:4096
Time to write: 258
Dump Index List
Drive # 2 Selected
Start write file: write_test_file.txt length:1048576 Write Size:512
Time to write: 1270
Start write file: write_test_file.txt length:1048576 Write Size:64
Time to write: 912
Start write file: write_test_file.txt length:1048576 Write Size:4096
Time to write: 263
Start write file: write_test_file.txt length:1048576 Write Size:512
Time to write: 802
Start write file: write_test_file.txt length:1048576 Write Size:64
Time to write: 788
Start write file: write_test_file.txt length:1048576 Write Size:4096
Time to write: 212
Is it just me or are there major race conditions in ehci.cpp? Lots of list manipulation happening without interrupts disabled and isr() being triggered can easily modify those same lists...
store:2 storage:30001 name:MSC0-126GEXFAT fs:200030cc
w 1048576 512 test.txt
CrashReport:
A problem occurred at (system time) 17:35:54
Code was executing from address 0x10E6
CFSR: 82
(DACCVIOL) Data Access Violation
(MMARVALID) Accessed Address: 0x20109222
Temperature inside the chip was 52.26 °C
Startup CPU clock speed is 600MHz
Reboot was caused by auto reboot after fault or bad interrupt detected
This would probably also explain why some of wwatson's drives are taking over 5 seconds to initialize.
Sorry, there is not much of checking in this code. Like most of the commands in that sketch, it runs off of the currently selected drive.@KurtE - Linux Arduino 1,.8.19 TD1.58B3 - Downloaded MTP_TEENY-MAIN.zip. Setup T4.1 and uploaded. All good. Then selected:
Ran this:Code:store:2 storage:30001 name:MSC0-126GEXFAT fs:200030cc
Code:w 1048576 512 test.txt
The T4.1 reset with:
Code:CrashReport: A problem occurred at (system time) 17:35:54 Code was executing from address 0x10E6 CFSR: 82 (DACCVIOL) Data Access Violation (MMARVALID) Accessed Address: 0x20109222 Temperature inside the chip was 52.26 °C Startup CPU clock speed is 600MHz Reboot was caused by auto reboot after fault or bad interrupt detected
Test.txt was created but size was zero. Tried with 3 flash drives,,,
// Make sure to compile for RawHID USB type.
// This sketch assumes you have migrated the latest changes to the MassStorageDriver
#include "USBHost_t36.h"
USBHost myusb;
USBHub hub1(myusb);
USBDrive usbDrive(myusb);
USBFilesystem usbPart(myusb);
USBHIDParser hid1(myusb);
RawHIDController rawHID1(myusb);
#define LEDPIN 13
void setup() {
Serial.begin(9600);
myusb.begin();
pinMode(LEDPIN, OUTPUT);
rawHID1.attachReceive(onReceiveHidData1);
Serial.print("Insert a USB Drive to begin test.\n");
}
bool testHasRun = false;
bool rawHIDConnected = false;
elapsedMillis testTime;
elapsedMillis ledTime;
elapsedMillis rawHIDTimer;
bool ledOn = false;
uint8_t buffer[64];
void loop() {
myusb.Task();
if (rawHIDTimer > 50) {
rawHIDTimer = 0;
RawHID.send(&buffer, 0);
}
if (rawHID1 != rawHIDConnected) {
rawHIDConnected = !rawHIDConnected;
if (rawHIDConnected)
Serial.print("Host port rawHID1 is connected\n");
else
Serial.print("Host port rawHID1 is disconnected\n");
}
if (ledTime > 100) {
ledTime = 0;
ledOn = !ledOn;
digitalWrite(LEDPIN, ledOn);
}
if (usbPart) {
if (!testHasRun) {
testHasRun = true;
performTest();
}
}
else {
testHasRun = false;
}
}
void performTest() {
Serial.println("Starting Tests");
testTime = 0;
Serial.print("Creating /testDir...");
if (!usbPart.mkdir("/testDir")) {
Serial.print("FAILED\n");
return;
}
Serial.print("SUCCESS\n");
File testFile[9];
for (int i = 0; i < 9; i++) {
char filename[50];
sprintf(filename, "/testDir/file_%1d.txt", i);
testFile[i] = usbPart.open(filename, FILE_WRITE_BEGIN);
if (!testFile[i]) {
Serial.print("Failed to create ");
Serial.println(filename);
}
if (testFile[i]) {
Serial.print("Writing to ");
Serial.println(filename);
testFile[i].write("Testing");
testFile[i].close();
if (!usbPart.remove(filename)) {
Serial.print("Failed to remove ");
Serial.println(filename);
}
}
}
Serial.print("Removing /testDir...");
if (!usbPart.rmdir("/testDir")) {
Serial.print("FAILED\n");
return;
}
Serial.print("SUCCESS\n");
Serial.print("Test completed in ");
Serial.print(testTime);
Serial.println(" miliseconds.");
Serial.println("Remove and reinsert media to test again.");
}
bool onReceiveHidData1(uint32_t usage, const uint8_t* data, uint32_t len) {
return true;
}
Hi, thank you again, both Sandisk drives working now, CSW error is gone, but Kingston Datatraveler G2 keeps initializing infinitely as shown here. Maybe the unit is too old and is faulty but works on Windows, what I've noticed is when I plug into PC the led light flashes, aswell when writing/reading, but not when I plug into teensy even being detected and reported in log.