SD Card Detection Without a Detect Hardware Signal

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SD Card Detection Without a Detect Hardware Signal

Jump to solution
3,388 Views
Vagni
Contributor IV

I am developing my application on a K60 cpu with KDS 2.0.0 and MQX 4.1.1. I have to handle an SD card with the SPI peripheral.

The MFS demo for SD card with SPI interface is based only on an available GPIO pin for the SD presence detection.

What about when no hardware signal is available to detect the SD card presence?

Well, I think first my firmware starts in the SD_NOT_PRESENT state and every 1 sec checks if fopen("sdcard:", 0) has success.

But what can I do when an SD card is detected and the file system is mounted on it to check the SD presence?

I could try every 1 sec to check the SD card status with:

_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD13_SEND_STATUS, 0, &r1, &r2, 1);

Unfortunatelly, that function is local for the sdcard_spi driver...

Is there a better way to check if the SD card was removed?

Also, in my application there could be one or more tasks that may want to access the SD card with the file system: I think a semaphore is needed in file system to perform the SD presence check.

1 Solution
1,768 Views
RadekS
NXP Employee
NXP Employee

Hi

Thank you for additional information.

Yes, when you call ioctl(sdcard_handle, ...), you call _io_sdcard_ioctl() function. This functions is registered in _io_sdcard_install() function.

Yes, definition of a new IO_IOCTL_SDCARD_GET_STATUS command is the clearest way how to do it.

Unfortunately there isn’t direct way for ioctl commands between Sdcard and Sdcard_spi driver.

sdcard_init_struct defined INIT_FUNC, READ_FUNC and WRITE_FUNC, but no IOCTL_FUNC – till now, we didn’t need it.

So, simplest way will be probably direct call _io_sdcard_spi_command() function in new case of _io_sdcard_ioctl() function and adding include of sdcard_SPI driver headers into sdcard.c file.

It is not clear solution, however it should work without modifications of sdcard_init_struct.

IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;

SDCARD_STRUCT_PTR sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR

This way you will get sdcard_ptr pointer.

I hope it helps you.    

Radek

View solution in original post

0 Kudos
7 Replies
1,768 Views
RadekS
NXP Employee
NXP Employee

Hi

you are right. This situation is not fully covered by MQX SDcard driver.

In fact, you can detect SDcard by switch at SDcard holder (as GPIO) or potentially you can use a pull-up resistor on DAT[3] to detect card insertion.

Unfortunately second option is quite difficult because pull-up resistor has to be disabled during data transfer…

From this point of view your propose looks reasonable.

In fact CMD13 should be common for both accesses (SD card and SPI).

Therefore we could use some code like:

        command.COMMAND = ESDHC_CREATE_CMD(13, ESDHC_COMMAND_TYPE_NORMAL, ESDHC_COMMAND_RESPONSE_R2, ESDHC_COMMAND_NONE_FLAG);

        command.ARGUMENT = 0;

        command.BLOCKS = 0;

        if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))

        {

            return IO_ERROR;

        }

Unfortunately I am not expert for SD card communication. It just shot from hip.

Additionally I would like to recommend use it only in case when ESDHC is not used. For that case we should use sdcard semaphore:

_lwsem_wait(&sdcard_ptr->LWSEM);

//check SDcard status code

_lwsem_post(&sdcard_ptr->LWSEM);

I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,768 Views
Vagni
Contributor IV

Thank you RadekS.

But I am using SD card with SPI, not with ESDHC...

I see in sdcard.c MQX source file the only commands handled by _io_sdcard_ioctl() function are:

  • IO_IOCTL_SET_BLOCK_MODE
  • IO_IOCTL_GET_BLOCK_SIZE
  • IO_IOCTL_GET_NUM_SECTORS
  • IO_IOCTL_GET_REQ_ALIGNMENT
  • IO_IOCTL_SDCARD_GET_CID
  • IO_IOCTL_DEVICE_IDENTIFY

In my application firmware I get an SD card handle (valid when SD card is present):

sdcard_handle = fopen("sdcard:", 0);

When I call ioctl(sdcard_handle, ...), I do call _io_sdcard_ioctl() function?

How should I use this handle to send the SDCARD_SPI_CMD13_SEND_STATUS command to the SD card?

Should I define a new IO_IOCTL_SDCARD_GET_STATUS command and write its handler code in _io_sdcard_ioctl() function? This handler code would call (in some way I don't know yet) the SPI-level function:

_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD13_SEND_STATUS, 0, &r1, &r2, 1);

And how to get the defined sdcard semaphore from that SD card handle?

0 Kudos
1,769 Views
RadekS
NXP Employee
NXP Employee

Hi

Thank you for additional information.

Yes, when you call ioctl(sdcard_handle, ...), you call _io_sdcard_ioctl() function. This functions is registered in _io_sdcard_install() function.

Yes, definition of a new IO_IOCTL_SDCARD_GET_STATUS command is the clearest way how to do it.

Unfortunately there isn’t direct way for ioctl commands between Sdcard and Sdcard_spi driver.

sdcard_init_struct defined INIT_FUNC, READ_FUNC and WRITE_FUNC, but no IOCTL_FUNC – till now, we didn’t need it.

So, simplest way will be probably direct call _io_sdcard_spi_command() function in new case of _io_sdcard_ioctl() function and adding include of sdcard_SPI driver headers into sdcard.c file.

It is not clear solution, however it should work without modifications of sdcard_init_struct.

IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;

SDCARD_STRUCT_PTR sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR

This way you will get sdcard_ptr pointer.

I hope it helps you.    

Radek

0 Kudos
1,768 Views
Vagni
Contributor IV

Hi Radek,

I wanted to do it in the clearest way.

I defined the new IOCTL_FUNC in sdcard_init_struct as the new _io_sdcard_spi_ioctl() function.

I defined a new IO_IOCTL_SDCARD_GET_STATUS command and a new SDCARD_STATUS_STRUCT.

I wrote a new case in _io_sdcard_ioctl() function to handle the IO_IOCTL_SDCARD_GET_STATUS command. In this new case the sdcard_ptr->LWSEM is get to call the IOCTL_FUNC function with the same command code.

The new _io_sdcard_spi_ioctl() function handles the only IO_IOCTL_SDCARD_GET_STATUS command case, calling _io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD13_SEND_STATUS, 0, &status_ptr->r1, &status_ptr->r2, 1), where status_ptr points to a SDCARD_STATUS_STRUCT structure passed as ioctl parameter.

And it works! Now I can handle my SD card without a detect hardware signal.

Thank you Radek.

Best Regards,

Alessandro

0 Kudos
1,768 Views
RadekS
NXP Employee
NXP Employee

Hi Alessandro,

You're welcome.

I am glad that the problem with card detect has been resolved.

Could you please share here modified SD card driver files, for potential customers with the same issue?

I will propose adding this driver feature into one of next releases however I am not sure if it will be possible or necessary. Unfortunately we will not be able add this into MQX 4.2/KSDK1.2 releases - they will be released soon. MQX 4.2 should be last “Clasic” MQX release and SD card driver will be part of MFS code in KSDK only until we will not be able use KSDK driver for MFS – this is one of next tasks for KSDK/MQX teams.

I wish you good luck in the future development.

Best Regards

RadekS

0 Kudos
1,768 Views
Vagni
Contributor IV

Hi Radek,

I attached the BSP source files I modified.

Best Regards,

Alessandro

1,768 Views
RadekS
NXP Employee
NXP Employee

Hi Alessandro,

Thank you very much for sharing.

Best Regards

RadekS

0 Kudos