cancel
Showing results for 
Search instead for 
Did you mean: 

STM322xg Eval board SDIO Problems

stbbrad3
Associate II
Posted on October 05, 2011 at 19:18

Hello all,

I have search through the forums and google for the exact problem I am having to no avail.

The issue I am having is regarding finding the filesystem on the SD card, in particular the check_fs function inside of chk_mounted. From what I understand the function will check for two different signatures. One is the BS_55AA at the end of the 512 byte block and the other is the FAT string somewhere within the block ( depending on the FAT subtype ).

The first signature 55AA is found, but only when I use the f_mkfs ( make filesystem ) in Chan's code. Using windows does not make the signature which I thought was part of any FAT file system. Regardless of which method I use to format the disk I cannot see the FAT string in the block anywhere.

Anyone have/had this issue or have insight as to what might be the problem? I have tried multiple allocation unit sizes when calling makefs.

EDIT: I have tried with both a 256MB and 2GB card. I have actually seen mixed results, but I always see FR_NO_FILESYSTEM.

EDIT2: So I can see when I am reading from the Volume Boot Record the MS DOS string is still at the top where it belongs but aftet that I get a bunch of FF's, enough to overwrite the FAT string.
16 REPLIES 16
infoinfo989
Associate III
Posted on October 05, 2011 at 22:38

I am using the ChanFS code.

Is this chk_fs function you're referring to part of the ChanFS code? I don't see it (or anything like it) on the ChanFS website API list.

http://elm-chan.org/fsw/ff/00index_e.html

I've been having no problems using fat32 filesystems created either by windows or by the f_mkfs() function.

You should certainly find 0x55 0xAA at the end of a couple of the sectors (for fat32 anyway). See:

http://en.wikipedia.org/wiki/File_Allocation_Table

You might want to print off a couple of the relevant sectors yourself, just to confirm those bytes actually are (or are not) present.

Gawie
Associate II
Posted on October 06, 2011 at 08:36

Hi h.brad

I have mentioned in a previous post that I experienced problems with 2G card on the STM32F2xx processor. If I can remember correctly, I have seen similar errors.I have attached my updated stm32_eval_sdio_sd.c (in theUtilities\STM32_EVAL\Common folder) for your reference.

The changes are as follows:

1. Changed the address variable for the SD_ReadBlock, SD_ReadMultiBlocks, SD_WriteBlock, SD_WriteMultiBlocks and SD_Erase function calls to reflect the sector address. Fixes the out-of-range issue for bigger cards.

2. Set Block Size for Card in the SD_ReadBlock, SD_WriteBlock and SD_WriteMultiBlocks function calls.

Hope this helps.

Cheers,

Gawie

________________

Attachments :

stm32_eval_sdio_sd.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HtQQ&d=%2Fa%2F0X0000000aPq%2FgtPC1.F8Z6WRSpqjgAPAYuU4jJ3fD3RmMYzn.D5NCOs&asPdf=false
stbbrad3
Associate II
Posted on October 06, 2011 at 14:40

Thanks for you insight guys! It appears my problem is solved. Justa  bit more tweeking to get my program to work.

Gawie,

Your solution provides the abilty to see the SD card is mounted and reads everything fine.

However, I still have the issue when I format the card using windows. I have narrowed it down somewhat and I can see I am getting SDIO RX Overrun when reading. This only happens when I format using windows and not the f_mkfs. It appears I am missing the last 128 bytes of the block which includes the aa55 signature.

I do plan on implementing DMA when I am finished testing without, for efficiency.

Thanks

Brad

stbbrad3
Associate II
Posted on October 06, 2011 at 17:33

stbbrad3
Associate II
Posted on October 07, 2011 at 15:11

Maybe someone could explain this to me?

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;

  SDIO_DataInitStructure.SDIO_DataLength = BlockSize;

  SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) 9 << 4;            // What is this?

 

  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;

  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;

  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;

  SDIO_DataConfig(&SDIO_DataInitStructure);

  /*!< Send CMD17 READ_SINGLE_BLOCK */

  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)ReadAddr;

  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_SINGLE_BLOCK;

  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;

  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;

  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;

  SDIO_SendCommand(&SDIO_CmdInitStructure);

Why is the block size 9 << 4? Looks like 144 bytes? Am I looking at this wrong?

By the way I am still having a bunch of issues. Out of no where f_mkfs started screwing my 2GB sd card up and windows was reading it as 67MB. Had to get a card formatter to fix it. And now I am back to not being able to read the VBR correctly. It appears like I am not reading sector 0 anymore, but I dont know why. The sector editor program I use shows the VBR is fine.

Man, who thought this would be such a hassle?
stbbrad3
Associate II
Posted on October 07, 2011 at 22:04

So I figured out the 9 << 4 is a 0x90 and is for defining block length to 512 bytes.

On another note I whent backwards and got rid of the FAT FS to test more with just using the SD as external memory.

If anyone can help me out here it would be appreciated. Here is my a small chunk of code.

#define BLOCK_SIZE   512

 

 

uint8_t Buffer_Block_Tx [BLOCK_SIZE];

 

 

 

  if((Status = DIL_SD_Init()) == SD_OK)

 

  {     

 

    // Enable specific interrupts

 

    SDIO_ITConfig ( SDIO_IT_DBCKEND | SDIO_IT_STBITERR | SDIO_IT_DTIMEOUT |

 

                    SDIO_IT_DCRCFAIL | SDIO_IT_TXUNDERR | SDIO_FLAG_TXFIFOHE |

 

                    SDIO_FLAG_TXFIFOE | SDIO_FLAG_RXFIFOF | SDIO_FLAG_RXFIFOE |

 

                    SDIO_FLAG_TXFIFOF | SDIO_FLAG_RXFIFOHF, ENABLE );

 

 

// Fill buffer with known data

 

Fill_Buffer(Buffer_Block_Tx, BLOCK_SIZE, 0x320F);

 

 

// Transmit buffer to SD card

 

Status = SD_WriteBlock ( Buffer_Block_Tx, 0x00, BLOCK_SIZE );

 

}

 

 

 

 

 

 

inside of SD_WriteBlock I am getting stuck in this loop....

    while ( !( SDIO->STA & ( SDIO_FLAG_DBCKEND  |

 

                             SDIO_FLAG_TXUNDERR |

 

                             SDIO_FLAG_DCRCFAIL |

 

                             SDIO_FLAG_DTIMEOUT |

 

                             SDIO_FLAG_STBITERR ) ) )

 

 

Why, if byteswritten = 512, is the DBCKEND flag never being set???? I am expecting this to happen. For some odd reason my Tx Half Full flag is still set as well......

Has anyone experienced this?

Thanks in advance

Brad
infoinfo989
Associate III
Posted on October 08, 2011 at 01:48

You are using an F2 part right? What are you using as your codebase? When I search stm32f2xx.h I don't see anything with the name SDIO_FLAG_DBCKEND 

Instead I see things like: SDIO_STA_DBCKEND

stbbrad3
Associate II
Posted on October 09, 2011 at 00:38

This is defined in stm32f2xx_sdio.h line 380.  as 0x0000000400

Either way the SDIO_STA registers DBCKEND is never setting.

 
infoinfo989
Associate III
Posted on October 09, 2011 at 03:32

I'm guessing the reason is because the data block is never completely sent. Either because it physically wasn't sent (eg the card was pulling busy or something), or more likely the processor sent the data, but the card never sent an acknowledgment, which would result in the processor sitting there waiting for the ack until its hardware timeout runs out.

The library example code sets the hardware timeout (SDIO_DTIMER register) to its maximum value, which means the timeout would take a really long time (hours or something). Writing a more reasonable value to that register would probably help you because your code is looking for that timeout bit. Alternatively, put your own timeout in the while() loop.

I would guess (and it's just a guess) that the card isn't in the state you want it to be. You probably want it to be in state 6, the receive state, if you're trying to send it a block of data, and it's probably not. Sending the card a CMD13 - SendStatus, will return the card's status register, which contains its current state number. Page 27 of the SD card spec shows the card internal state machine.