|
|
View previous topic :: View next topic |
Author |
Message |
Audi80
Joined: 07 Sep 2007 Posts: 41
|
Reading block 0 from sd card |
Posted: Fri Oct 09, 2009 4:26 am |
|
|
Hi there, i´ve a project that´s already working and what it does is playing MP3 files using a VS1011 and a SD card. The problem is that i´ve made a few project and delivered them using 1Gb card from Silicon Power. The software starts reading the boot sector to get the root directory firstSector and then the song list sectors and so on... The problem is that has been requested more units so i went to the store and brought 2Gb cards from Kingston and now i cant read the first sector and i´ve already tried with:
2Gb From Kingston
1Gb From OnMemory
2Gb From SanDisk
And some more that i dont remember.
Does anyone had the same problem? Can anyone help me? Wold be very apreciated. Here´s the example code:
Code: |
int mmc_init(){
char p;
int i;
//SETUP_SPI(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
SETUP_SPI(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
SSPSTAT |= 0x40;
SSPCON &= 0xEF;
SS=1;
for(i=0;i<10;i++){
SPI_WRITE(0xFF);
delay_us(1);
}
SS=0;
SPI_WRITE(0x40);
delay_us(1);
for(p=4;p>0;p--){
SPI_WRITE(0x00);
delay_us(1);
}
SPI_WRITE(0x95);
delay_us(1);
if(mmc_response(0x01)==1) return 1;
i = 0;
while((i < 255) && (mmc_response(0x00)==1)){
SPI_WRITE(0x41);
delay_us(1);
for(p=4;p>0;p--){
SPI_WRITE(0x00);
delay_us(1);
}
SPI_WRITE(0xFF);
delay_us(1);
i++;
}
if(i >= 254) return 1;
SS=1;
SPI_WRITE(0xFF);
delay_us(1);
SS=0;
SPI_WRITE(0x50);
delay_us(1);
SPI_WRITE(0x00);
delay_us(1);
SPI_WRITE(0x00);
delay_us(1);
SPI_WRITE(0x02);
delay_us(1);
SPI_WRITE(0x00);
delay_us(1);
SPI_WRITE(0xFF);
delay_us(1);
if((mmc_response(0x00))==1) return 1; //(bad!)
SS=1;
return 0;
}
int mmc_response(unsigned char response){
unsigned long count = 0x0FFF;
while(SPI_READ(0xFF) != response && --count > 0){
delay_us(1);
}
if(count==0) return 1;
else return 0;
}
char mmc_open_block(int32 block_number){
char c = 0x00;
block_number*=512;
printf("Block Number %lu\r\n ",block_number);
SS=0;
SPI_WRITE(0x51);
delay_us(1);
SPI_WRITE(*(((char*)&block_number)+3));
delay_us(1);
SPI_WRITE(*(((char*)&block_number)+2));
delay_us(1);
SPI_WRITE(*(((char*)&block_number)+1));
delay_us(1);
SPI_WRITE(0x00);
delay_us(1);
SPI_WRITE(0xFF);
delay_us(1);
while(1){
c = SPI_READ(0xFF);
printf("0x%02X\r\n",c);
if(c == 0xFE) break;
delay_us(1);
}
SS=1;
return 0;
}
void getRootDirectory(){
long reservedSectors = 0;
long sectorPerFat = 0;
char aux[5];
int i;
int j;
memset(aux,0,sizeof(aux));
while(1){
if(mmc_open_block(0))printf("Error opening block\r\n");
else {
printf("Block opened!!!\r\n");
break;
}
}
SS = 0;
for(i=0;i<14;++i){
printf("0x%02X ",SPI_READ(0xFF));
delay_us(1);
}
while(1);
for(i=0;i<2;++i){
aux[i]=SPI_READ(0x00);
delay_us(1);
}
j=2;
while(j!=0){
reservedSectors = (reservedSectors<<8) | (aux[j-1]);
--j;
}
memset(aux,0,sizeof(aux));
for(i=0;i<20;++i){
SPI_WRITE(0x00);
delay_us(1);
}
for(i=0;i<4;++i){
aux[i]=SPI_READ(0x00);
delay_us(1);
}
j=4;
while(j!=0){
sectorPerFat = (sectorPerFat<<8) | (aux[j-1]);
--j;
}
firstSector=reservedSectors+sectorPerFat*2;
printf("Reserved Sectors: %lu \n\r",reservedSectors);
printf("Sectors per fat: %lu \n\r",sectorPerFat);
printf("First sector: %lu \n\r",firstSector);
SS = 1;
while(1);
mmc_cancel_block();
}
void init(void){
tris_a = 0b01101100;
tris_b = 0b00010110;
tris_c = 0b11010011;
tris_d = 0b01010010;
tris_e = 0b00000000;
xcs=1;
xdcs=1;
volume=0x20;
while(mmc_init()!=0 ){
delay_ms(100);
printf("**** ERROR INITIATING SD CARD **** \r\n");
}
printf("SD CARD INITIATED...\r\n");
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Oct 12, 2009 8:05 am |
|
|
Code: | SETUP_SPI(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
SSPSTAT |= 0x40;
SSPCON &= 0xEF;
SS=1; | I haven't checked this result of this code (and register definitions are missing anyway) but it is dirty to combine CCS SPI setup code with direct register writing. Use one method, whichever you like, but don't mix them.
Never use SPI_SS_DISABLED on a master! The Slave Select pin is only present in the slave. Setting this define creates an invalid configuration for the master with unknown results.
Another possible problem is that the 2Gb cards take more time to initialise than the 1Gb cards. Your mmc_init function has some hard coded timeout loops that are not compliant to the MMC standard as far as I remember. Have a look at the CCS supplied example file (ex_mmcsd.c ?) |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|