Teensy 3.6 SD card detect

Status
Not open for further replies.

posse

Member
Hi!

Does the Teensy3.6 SD card housing feature a card detect pin wired into the microprocessor ? And if so, is it accessible from the Arduino environment ?

Thanks in advance.
 
I don't think there is a separate pin. The driver uses the SDHC_IRQSTAT register which has bits indicating card has been removed or inserted.
https://github.com/PaulStoffregen/SD/blob/master/utility/KinetisSDHC.c
also see SDHC_PRSSTAT register CINS bit

Thanks for the reply. I can't seem to be able to read the SDHC_IRQSTAT register, and the CINS bit of the SDHC_PRSSTAT doesn't change state when I insert/remove a card. I'm currently using the SDFat-beta library, with the following code to present the SDHC_PRSSTAT register value:

Serial.print("Test: ");
Serial.flush();
uint32_t m_irqstat = SDHC_PRSSTAT;
Serial.println(m_irqstat, BIN);

Is this the right way to check if a card is present?

Thanks
 
sd.begin() will fail if no card. and you need sd.begin() to enable the SD peripheral registers. you'll need to read the reference manual or inspect the SD library code to figure out the semantics.
 
I am able to read the SDHC_PRSSTAT register, while seeing bits changing. The SDFat library also features a similar way to check for the CINS bit, but this bit doesn't change at all.

Worse, further research has led me to this thread https://forum.pjrc.com/threads/4121...-SD-Card-does-not-always-initialize?styleid=2, where user UhClem says "A waste of time since the problem is with the card detect debounce logic of the SDHC interface and has nothing to do with the card. Worse, the card detection doesn't work because DAT3 is pulled high. Even worse, the internal pull down resistors are too small a value to work reliably.".

I have found other information online sustaining this sentence, as SD cards should have an internal pull-up of 10KOhm in DAT3 and the host should have a pull-down in the same line, to allow SD Card detection. In the teensy 3.6 case, such a pull-down is not present in the hardware. The correspondent microchip pin is PTE4/LLWU_P2. From further inspection to the reference manual (pg182 of http://www.nxp.com/assets/documents/data/en/reference-manuals/K66P144M180SF5RMV2.pdf), it seems an internal pull-down is available. The product datasheet states that internal pull-down resistors have a value of 20-50KOhm (pg9 of https://www.pjrc.com/teensy/K66P144M180SF5V2.pdf).

Can this information be confirmed? If possible, how can this pull-down resistor be enabled? Could this work reliably with the resistor values above? Or would the schematic need to be revised for such a feature to work correctly?

Thank you in advance
 
Ok so I actually solved this!

It seems all the above is correct and can be solved only with software.

The SDFat library configures the DAT3 line with a pull-up resistor through the command:

PORTE_PCR4 = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_PS | PORT_PCR_PE;

Resetting the PORT_PCR_PS bit returns the pin to it's default pull-down resistor. The final step is enabling the card detect feature in the DAT3 line, using SDHC_PROCTL |= SDHC_PROCTL_D3CD;

After this, bit 16 of the SDHC_PRSSTAT can be checked for card detection.

All after the sd.begin() command.

Thank you very much for the help :)
 
Hi,

I just found this very useful thread, could you please give a little further information as to what part/where in the SDFat library I can find the DAT3 configuration you've noted above, I'd really like to include this in my project.

Should I be editing the SDFat library to implement this or can I just change the registers after issuing sd.begin()? You're background work on this is much appreciated.

Thanks very much for this info either way,
Pat
 
Hi,

Please bear in mind that this is in no way the optimal way to do this. I have been using this change with no drawback, but that doesn't mean it doesn't have one.

With this in mind, you don't need to change the SDFat library. After a successful sd.begin() (remember this returns false when no card is detected) you can simply execute the two lines above to enable card detection on the SDHC_PRSSTAT register. A simple example code would be:

if (!sd.begin())
return;

SDHC_PROCTL |= SDHC_PROCTL_D3CD;
PORTE_PCR4 = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_PE;

And then the card can be detected by the following code example:

bool cardDetect(void) { return ((SDHC_PRSSTAT >> 16) & 0x01); }



Hi,

I just found this very useful thread, could you please give a little further information as to what part/where in the SDFat library I can find the DAT3 configuration you've noted above, I'd really like to include this in my project.

Should I be editing the SDFat library to implement this or can I just change the registers after issuing sd.begin()? You're background work on this is much appreciated.

Thanks very much for this info either way,
Pat
 
I have been using this change with no drawback, but that doesn't mean it doesn't have one.

For me on my teensy 3.6 and couple of SD Cards, this approach works fine until files are read from the SDCard, then it always returns card present.

Checked the SDHC_PROCTL and PORTE_PCR4 registers when this happens, and they are still setup with the correct bit values, i.e. SdFat hasn't overwritten them.

I believe the internal pulldown in the K66 isn't strong enough to work reliably, see this post:
https://github.com/greiman/SdFat-beta/issues/16
 
Hi,
I had trouble with the above method of detecting the presence of the SD card also so I reverted to the less desirable method of polling. However as I primarily use capacitive touch TFT's, I also have to poll a register to see if there has been a user interaction, so as part of this this function I also get sd fat to check for the existence of a setup file that's permanently on my SD card (i've a settings file that's used upon startup so I use that but any file or folder should work). If it's present, the code simply continues, otherwise I its set to restart the T3.6. Example:

if (!sd.exists("settings.txt")) { CPU_RESTART }

where these are defined earlier in the code for restarting:
#define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
#define CPU_RESTART_VAL 0x5FA0004
#define CPU_RESTART (*CPU_RESTART_ADDR = CPU_RESTART_VAL);

I find it rather reliable and results in a restart the moment someone pulls the SD card so hopefully of some use. I also have another function in setup to continuously attempt sd.begin() during which a vector drawn image of an SD card being inserted into the slot is painted and scrolled on the TFT. In my application nothing works without the SD so restart is good for me but I understand it may not be suitable for others, in this case you could include a function for sd.begin if the file doesn't exist and it should respond.
 
I'm digging up old thread for the purpose of helping people who find it.
This method does not work now on Teensy 4.1, not sure why. I think the library will happily cache directories and return files even after the card is removed from the socket.

Does anyone know how one can detect the card being removed apart for waiting for a error?
 
Status
Not open for further replies.
Back
Top