2011-10-05 10:18 AM
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.2011-10-05 01:38 PM
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. 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: You might want to print off a couple of the relevant sectors yourself, just to confirm those bytes actually are (or are not) present.2011-10-05 11:36 PM
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=false2011-10-06 05:40 AM
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 Brad2011-10-06 08:33 AM
2011-10-07 06:11 AM
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?2011-10-07 01:04 PM
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
2011-10-07 04:48 PM
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_DBCKEND2011-10-08 03:38 PM
This is defined in stm32f2xx_sdio.h line 380. as 0x0000000400
Either way the SDIO_STA registers DBCKEND is never setting.2011-10-08 06:32 PM
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.