MTP Responder in real SDfat environment problem

Status
Not open for further replies.

Darcy

Well-known member
I tested MTP and it works great stand-alone, but now I have it in my project it appears to interfere with the current working directory or maybe the volume working directory.
My File structure is dynamic (sub-folders are named YYYYMMDD and my files are named HHMMSS by calling RTC time) and this prevents me from calling open files using a full path, and forces the use of the chdir() command.

I (think) I have isolated the odd behaviour into a working example, that successfully creates 3 files in the setup, but then fails once MTP is running in the loop. (code below)

Should I try and separate MTP and normal SD usage in code by disabling the interrupt?
Am I doing anything obviously stupid?

Code:
#include <MTP.h>
#include <SdFat.h>

MTPStorage_SD storage;
MTPD          mtpd(&storage);

volatile int  status = 0;
volatile int  writenow = 0;
volatile bool sdfound = 0;
volatile int  MTPcount = 1;

void rtc_seconds_isr() {
  if (MTPcount-- == 0) {
    // digitalWrite(LED_BUILTIN, status);
    Serial.println("I should be commented out");
      writenow = true;
    // status = !status;
    if (sdfound)
      MTPcount = 2;
    else
      MTPcount = 1;
  }
}

SdFatSdioEX sd;
ArduinoOutStream cout(Serial); //create a serial out stream

File logfile;
#define FILE_BASE_NAME "000000"
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
const uint8_t FILE_NAME_DIM  = BASE_NAME_SIZE + 7;

char logfolder[] = "LOGFILES";
char subfolderName[] = "SUBFOLDR";
char logfileName[] = "1000_001.bin";

#define error(s) sd.errorHalt(F(s))

// -------------------------------------------------------------
void setup(void)
{
	  Serial.begin(19200);
  pinMode(LED_BUILTIN, OUTPUT);
  ///////////////mtp setup/////////////////////////////////////////////////////////////
  RTC_IER |= 0x10;  // Enable seconds IRQ from RTC peripheral
  NVIC_ENABLE_IRQ(IRQ_RTC_SECOND); // Enable seconds IRS function in NVIC
//////////////////////////////////////////////////////////////////////////////////////
 
  Serial.println(F("Hello Teensy 3.6 dual CAN Test With Objects."));
  Serial.print("Initializing SD card...");
     // see if the card is present and can be initialized:
      if (!sd.begin()) {
        Serial.println("card fail.");
    }
    
    else {
        sd.chvol(); // make sd the current volume.
        Serial.println("card initialized."); 
    }
  createfile();
  createfile();
  createfile();
}

void loop() {
  if (SD.begin()) {
    sdfound = true;
    mtpd.loop();
  }
  else {
    sdfound = false;

  }

 if (writenow) {
   createfile();
  writenow = false;
 }
}

void createfile() {
    sd.chvol();
    sd.vwd()->rewind();        // rewind to root directory
     if (!sd.chdir()) {             // change dir to root
        Serial.println("chdir failed for Root"); 
         } 
   
   if (!sd.exists(logfolder))  {         
      if (!sd.mkdir(logfolder)) {
         Serial.println("Create LOGFILES folder failed");
         }
      }
    if (!sd.chdir(logfolder)) {           
    Serial.println("chdir failed for LOGFILES");
  }  
  

   if (!sd.exists(subfolderName))  {      
     if (!sd.mkdir(subfolderName)) {
       Serial.println("Create SUBFOLDR folder failed");
       }
    }
   if (!sd.chdir(subfolderName)) {
     Serial.println("chdir failed for SUBFOLDR");
    }
  

 while (sd.exists(logfileName)) {
    if (logfileName[BASE_NAME_SIZE + 1] != '9') {
      logfileName[BASE_NAME_SIZE + 1]++;
    } else if (logfileName[BASE_NAME_SIZE] != '9') {
      logfileName[BASE_NAME_SIZE + 1] = '0';
      logfileName[BASE_NAME_SIZE]++;
    } else {
      Serial.println("Can't create file name");
    }
  }


     if (!logfile.open(logfileName, O_RDWR | O_CREAT)) {
          Serial.println("open failed");
        } 
         logfile.close();
}

Any help much appreciated.
 
Ok I have made some progress just by throwing lines in randomly as I really do not know how SDfat or MTP work...

The addition of :
File root;
setup { root = SD.open("/"); }
loop { sd.ls("/", LS_R); }

has the code working. Will have to see if it still works when my 10000 lines of code are added back in.

This is the demo code that works:
Code:
#include <MTP.h>
#include <SdFat.h>

MTPStorage_SD storage;
MTPD          mtpd(&storage);

volatile int  status = 0;
volatile int  writenow = 0;
volatile bool sdfound = 0;
volatile int  MTPcount = 1;

void rtc_seconds_isr() {
  if (MTPcount-- == 0) {
    // digitalWrite(LED_BUILTIN, status);
    Serial.println("I should be commented out");
      writenow = true;
    // status = !status;
    if (sdfound)
      MTPcount = 2;
    else
      MTPcount = 1;
  }
}

SdFatSdioEX sd;
ArduinoOutStream cout(Serial); //create a serial out stream

File logfile;
File root;
#define FILE_BASE_NAME "000000"
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
const uint8_t FILE_NAME_DIM  = BASE_NAME_SIZE + 7;

char logfolder[] = "LOGFILES";
char subfolderName[] = "SUBFOLDR";
char logfileName[] = "1000_001.bin";

#define error(s) sd.errorHalt(F(s))

// -------------------------------------------------------------
void setup(void)
{
	  Serial.begin(19200);
  pinMode(LED_BUILTIN, OUTPUT);
  ///////////////mtp setup/////////////////////////////////////////////////////////////
  RTC_IER |= 0x10;  // Enable seconds IRQ from RTC peripheral
  NVIC_ENABLE_IRQ(IRQ_RTC_SECOND); // Enable seconds IRS function in NVIC
//////////////////////////////////////////////////////////////////////////////////////
 
  Serial.println(F("Hello Teensy 3.6 dual CAN Test With Objects."));
  Serial.print("Initializing SD card...");
     // see if the card is present and can be initialized:
      if (!sd.begin()) {
        Serial.println("card fail.");
    }
    
    else {
        sd.chvol(); // make sd the current volume.
        Serial.println("card initialized."); 
    }
      root = SD.open("/");
  

  
  Serial.println("done!");
  createfile();
  createfile();
  createfile();
}

void loop() {
  if (SD.begin()) {
    sdfound = true;
    mtpd.loop();
  }
  else {
    sdfound = false;

  }

 if (writenow) {
   createfile();
  writenow = false;
 }
}

void createfile() {
    sd.chvol();
    sd.vwd()->rewind();        // rewind to root directory
     if (!sd.chdir()) {             // change dir to root
        Serial.println("chdir failed for Root"); 
         } 
   
   if (!sd.exists(logfolder))  {         
      if (!sd.mkdir(logfolder)) {
         Serial.println("Create LOGFILES folder failed");
         }
      }
    if (!sd.chdir(logfolder)) {           
    Serial.println("chdir failed for LOGFILES");
  }  
  

   if (!sd.exists(subfolderName))  {      
     if (!sd.mkdir(subfolderName)) {
       Serial.println("Create SUBFOLDR folder failed");
       }
    }
   if (!sd.chdir(subfolderName)) {
     Serial.println("chdir failed for SUBFOLDR");
    }
  

 while (sd.exists(logfileName)) {
    if (logfileName[BASE_NAME_SIZE + 1] != '9') {
      logfileName[BASE_NAME_SIZE + 1]++;
    } else if (logfileName[BASE_NAME_SIZE] != '9') {
      logfileName[BASE_NAME_SIZE + 1] = '0';
      logfileName[BASE_NAME_SIZE]++;
    } else {
      Serial.println("Can't create file name");
    }
  }


     if (!logfile.open(logfileName, O_RDWR | O_CREAT)) {
          Serial.println("open failed");
        } 
         logfile.close();
          sd.ls("/", LS_R);

}

EDIT: tried in my full project and only partially working, Logfile creates OK but subsequent file operations and folder navigating is failing....grrrr!
 
Last edited:
Yes, from memory I temporarily disable the MTP interupt whenever I access the sd card in my sketch, then re-enable when I have finished. This then allows file transfer to PC through the USB cable once datalogging is complete. I couldn't do concurrent access (PC and Teensy at the same time)

Darcy
 
Would you be willing to share your code?

I have an application where I want the user to put the teensy into “disk mode” so they can access the SD card that is buried in the enclosure, and then when they’re done they can exit disk mode to use the teensy for other purposes. Would this be possible?

Have you been able to compile the teensy with Serial Port, MIDI etc in addition to the MTP?
 
Status
Not open for further replies.
Back
Top