bool MTPStorage_SD::rename(uint32_t handle, const char* name)
{ char oldName[256];
char newName[256];
[B]char [COLOR=#ff0000]temp[64];[/COLOR][/B]
uint16_t store = ConstructFilename(handle, oldName, 256);
Serial.println(oldName);
Record p1 = ReadIndexRecord(handle);
strcpy(temp,p1.name);
strcpy(p1.name,name);
For the whole filename including multiple directories.On the other hand, all the rest of the Code (SdFat) uses 256. So why restrict here.
uint16_t MTPStorage_SD::ConstructFilename(int i, char* out, int len) // construct filename rexursively
{
Record tmp = ReadIndexRecord(i);
if (tmp.parent==(unsigned)i)
{ strcpy(out, "/");
return tmp.store;
}
else
{ ConstructFilename(tmp.parent, out, len);
if (out[strlen(out)-1] != '/') strcat(out, "/");
if(((strlen(out)+strlen(tmp.name)+1) < (unsigned) len)) strcat(out, tmp.name);
return tmp.store;
}
}
Just to jump in here for a minute.
As Frank and Paul said it would probably be safer in the long run would probably be better to use strlcpy().
As for filename length whatever gets decided probably should make sure they are all compatible between classes, SDFat, FS, LittleFS, and MTP. I would think.
As for USB interface was poking around usb_desc.h and .cpp and did notice that number of endpoints are different between the 2 for MTP. In desc.c its defined as 3 and in desc.h its defined as 4. Tried making them the same but.. as a test I changed it to 4 in the desc.c but then the Teensy as a device wouldn't show up. If I change it to 3 in desc.h I can copy those 2 jpgs to RAM, qspi, SD Card and the winbond flash on the breakout but it fails to copy to propshield flash and basically hangs MTP and I have to restart the T4.1
#define MAX_FILENAME_LEN 256
- On USB: maybe there is a mis-undestanding desc.c indicates the number of entrypoind and there are 3 RX,TX,Event, while desc.h indicates RX and TX use channel 4 and Event use channel 5
char buf[11]; // serial
for (size_t i=0; i<10; i++) buf[i] = usb_string_serial_number.wString[i];
writestring(buf);
uint32_t MTPStorage_SD::Create(uint32_t storage, uint32_t parent, bool folder, const char* filename)
{
uint32_t ret;
#if DEBUG==1
Serial.printf("SCR: %s\n",filename);
#endif
if (parent == 0xFFFFFFFFUL) parent = storage-1;
Record p = ReadIndexRecord(parent);
Record r;
[COLOR="#FF0000"] if (strlen(filename) > 62) return 0;[/COLOR]
strcpy(r.name, filename);
void MTPStorage_SD::write(const char* data, uint32_t bytes)
{
#if DEBUG==1
Serial.printf(" SW: %u\n",bytes);
#endif
void MTPStorage_SD::close()
{
#if DEBUG==1
Serial.printf("SCL - start");
#endif
mtp_lock_storage(true);
uint32_t size = (uint32_t) file_.size();
file_.close();
mtp_lock_storage(false);
//
// update record with file size
Record r = ReadIndexRecord(open_file_);
r.child = size;
WriteIndexRecord(open_file_, r);
open_file_ = 0xFFFFFFFEUL;
#if DEBUG==1
Serial.printf("SCL - complete\n");
#endif
}
100c 20 1 70: 4 ffffffff ffffffff
SCR: IMG_1255.jpg
2001 24 3 70: 4 ffffffff b
100d 12 1 71: 0 3000 177b5
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 6069
SCL - startSCL - complete2001 12 3 71: 0 aa65d7bb 3fad00ff
9803 20 1 72: b dc02 3fad00ff
2001 20 3 72: b dc02 3fad00ff
9803 20 1 73: b dc01 3fad00ff
2001 20 3 73: b dc01 3fad00ff
9803 20 1 74: b dc07 3fad00ff
2001 20 3 74: b dc07 3fad00ff
9802 20 1 75: dc0b 3000 3fad00ff
2001 20 3 75: dc0b 3000 3fad00ff
9803 20 1 76: b dc0b 3fad00ff
2001 20 3 76: b dc0b 3fad00ff
9803 20 1 77: b dc41 3fad00ff
2001 20 3 77: b dc41 3fad00ff
9803 20 1 78: b dc44 3fad00ff
2001 20 3 78: b dc44 3fad00ff
9803 20 1 79: b dc03 3fad00ff
2001 20 3 79: b dc03 3fad00ff
9803 20 1 80: b dc04 3fad00ff
2001 20 3 80: b dc04 3fad00ff
1008 16 1 81: b dc04 3fad00ff
2001 16 3 81: b dc04 3fad00ff
1005 16 1 82: 4 dc04 3fad00ff
2001 16 3 82: 4 dc04 3fad00ff
100c 20 1 83: 4 ffffffff 3fad00ff
SCR: T4-Cardlike.jpg
2001 24 3 83: 4 ffffffff c
100d 12 1 84: 0 3000 5321e
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
SW: 8192
#include "Arduino.h"
#include "SD.h"
#include "MTP.h"
#include "usb1_mtp.h"
#define HAVE_LITTLEFS 1 // set to zero if no LtttleFS is existing or to be used
#if HAVE_LITTLEFS==1
#define USE_RAM 1
#define USE_SPI 1
#define USE_QSPI 1
#define USE_HS_QSPI 1
#endif
/**** Start device specific change area ****/
// edit SPI to reflect your configuration (following is fot T4.1)
#define SD_MOSI 11
#define SD_MISO 12
#define SD_SCK 13
#define SPI_SPEED SD_SCK_MHZ(16) // adjust to sd card
// SDClasses
const char *sd_str[]={"sdio"}; // edit to reflect your configuration
const int cs[] = {BUILTIN_SDCARD}; // edit to reflect your configuration
const int nsd = sizeof(cs)/sizeof(int);
SDClass sdx[nsd];
//LittleFS classes
#if HAVE_LITTLEFS==1
#include "LittleFS.h"
#if USE_RAM == 1
const char *ram_str[]={"RAM0", "RAM1"}; // edit to reflect your configuration
const int ram_size[] = {2'000'000, 4'000'000};
const int ram_nsd = sizeof(ram_size)/sizeof(int);
LittleFS_RAM ramfs[ram_nsd]; // needs to be declared if LittleFS is used in storage.h
#endif
#if USE_SPI == 1
const char *spi_str[]={"PROPSHIELD", "WINBOND"}; // edit to reflect your configuration
const int spi_cs[] = {6, 10}; // edit to reflect your configuration
const int spi_nsd = sizeof(spi_cs)/sizeof(int);
LittleFS_SPIFlash spifs[spi_nsd]; // needs to be declared if LittleFS is used in storage.h
#endif
#if USE_QSPI == 1
const char *qspi_str[]={"QSPI0"}; // edit to reflect your configuration
const int qspi_nsd = 1;
LittleFS_QSPIFlash qspifs[qspi_nsd]; // needs to be declared if LittleFS is used in storage.h
#endif
#endif
MTPStorage_SD storage;
MTPD mtpd(&storage);
void storage_configure()
{
#if defined SD_SCK
SPI.setMOSI(SD_MOSI);
SPI.setMISO(SD_MISO);
SPI.setSCK(SD_SCK);
#endif
for(int ii=0; ii<nsd; ii++)
{ if(cs[ii] == BUILTIN_SDCARD)
{
if(!sdx[ii].sdfs.begin(SdioConfig(FIFO_SDIO))) {Serial.println("No storage"); while(1);};
storage.addFilesystem(sdx[ii], sd_str[ii]);
}
else if(cs[ii]<BUILTIN_SDCARD)
{
pinMode(cs[ii],OUTPUT); digitalWriteFast(cs[ii],HIGH);
if(!sdx[ii].sdfs.begin(SdSpiConfig(cs[ii], SHARED_SPI, SPI_SPEED))) {Serial.println("No storage"); while(1);}
storage.addFilesystem(sdx[ii], sd_str[ii]);
}
uint64_t totalSize = sdx[ii].totalSize();
uint64_t usedSize = sdx[ii].usedSize();
Serial.printf("Storage %d %d %s ",ii,cs[ii],sd_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
}
#if HAVE_LITTLEFS==1
#if USE_RAM == 1
for(int ii=0; ii<ram_nsd;ii++)
{
{ if(!ramfs[ii].begin(ram_size[ii])) { Serial.println("No storage"); while(1);}
storage.addFilesystem(ramfs[ii], ram_str[ii]);
}
uint64_t totalSize = ramfs[ii].totalSize();
uint64_t usedSize = ramfs[ii].usedSize();
Serial.printf("Storage %d %s ",ii,ram_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
}
#endif
#if USE_SPI == 1
for(int ii=0; ii<spi_nsd;ii++) {
pinMode(spi_cs[ii],OUTPUT); digitalWriteFast(cs[ii],HIGH);
if(!spifs[ii].begin(spi_cs[ii], SPI)) {Serial.println("No storage"); while(1);}
storage.addFilesystem(spifs[ii], spi_str[ii]);
uint64_t totalSize = spifs[ii].totalSize();
uint64_t usedSize = spifs[ii].usedSize();
Serial.printf("Storage %d %d %s ",ii,spi_cs[ii],spi_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
}
#endif
#if USE_QSPI == 1
for(int ii=0; ii<qspi_nsd;ii++) {
if(!qspifs[ii].begin()) {Serial.println("No storage"); while(1);}
storage.addFilesystem(qspifs[ii], qspi_str[ii]);
uint64_t totalSize = qspifs[ii].totalSize();
uint64_t usedSize = qspifs[ii].usedSize();
Serial.printf("Storage %d %s ",ii,qspi_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
}
#endif
#endif
}
/**** End of device specific change area ****/
// Call back for file timestamps. Only called for file create and sync(). needed by SDFat-beta
#include "TimeLib.h"
void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10)
{ *date = FS_DATE(year(), month(), day());
*time = FS_TIME(hour(), minute(), second());
*ms10 = second() & 1 ? 100 : 0;
}
void logg(uint32_t del, const char *txt)
{ static uint32_t to;
if(millis()-to > del)
{
Serial.println(txt);
to=millis();
}
}
void setup()
{
while(!Serial);
Serial.println("MTP_test");
// Set Time callback // needed for SDFat-beta
FsDateTime::callback = dateTime;
#if USE_HS_QSPI == 1
//Reset clock to 132.9 Mhz
CCM_CCGR7 |= CCM_CCGR7_FLEXSPI2(CCM_CCGR_OFF);
CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_FLEXSPI2_PODF_MASK | CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK))
| CCM_CBCMR_FLEXSPI2_PODF(4) | CCM_CBCMR_FLEXSPI2_CLK_SEL(2);
CCM_CCGR7 |= CCM_CCGR7_FLEXSPI2(CCM_CCGR_ON);
#endif
usb_mtp_configure();
storage_configure();
#if HAVE_LITTLEFS==1
#if USE_RAM
// store some files into disks (but only once)
for(int ii=0; ii<10;ii++)
{ char filename[80];
sprintf(filename,"test_%d.txt",ii);
if(!ramfs[0].exists(filename))
{
File file=ramfs[0].open(filename,FILE_WRITE_BEGIN);
file.println("This is a test line");
file.close();
}
}
#endif
#endif
const char *str = "test1.txt";
if(sdx[0].exists(str)) sdx[0].remove(str);
File file=sdx[0].open(str,FILE_WRITE_BEGIN);
file.println("This is a test line");
file.close();
Serial.println("\n**** dir of sd[0] ****");
sdx[0].sdfs.ls();
Serial.println();
Serial.println("Setup done");
Serial.flush();
}
void loop()
{
mtpd.loop();
//logg(1000,"loop");
//asm("wfi"); // may wait forever on T4.x
}
I've added a PR that adds usage of the real Teensy serialnumber instead of the fixed #define MTP_SERNR "1234"
View attachment 22560
Was quite easy:
Should, in theory, work with all Teensy-models. Tested with T4.1 only.Code:char buf[11]; // serial for (size_t i=0; i<10; i++) buf[i] = usb_string_serial_number.wString[i]; writestring(buf);
This is all fun.. great field to play..
#define SPICONFIG SPISettings(50000000, MSBFIRST, SPI_MODE0)
#define SPICONFIG SPISettings(30000000, MSBFIRST, SPI_MODE0)
But also was wondering about that hard coded 62?Code:uint32_t MTPStorage_SD::Create(uint32_t storage, uint32_t parent, bool folder, const char* filename) { uint32_t ret; #if DEBUG==1 Serial.printf("SCR: %s\n",filename); #endif if (parent == 0xFFFFFFFFUL) parent = storage-1; Record p = ReadIndexRecord(parent); Record r; [COLOR="#FF0000"] if (strlen(filename) > 62) return 0;[/COLOR] strcpy(r.name, filename);
strlcpy(r.name, filename,MAX_FILENAME_LEN);