#byte SSPCON1 = 0xFC6
#byte SSPSTAT = 0xFC7
#byte SSPBUF= 0xFC9
#byte PIR1=0xF9E
int const cmd[]={0x40,0x41,0xff,0x4A,0x49,0x51,0x58,0x50};
int const lTimeout=0x2fff;
#inline
int Leer_1Byte_SPI(){
SSPBUF=0xff; // envia puros unos en dataout
while(!bit_test(PIR1,3)){};
// mientras SSPIF=0 la transmisión contínua
// si SSPIF=1, terminó la transmisión. SSPIF-> PIR1,3
bit_clear(PIR1,3); // borro el flag SSPIF
return(SSPBUF);
}
//--------------------------------------------------------------
#inline
int Escribir_1Byte_SPI(int dato){
SSPBUF=dato;
if(SSPCON1 & 0x80){
return(0xff);
}
else{
while(!bit_test(PIR1,3)){};
// mientras SSPIF=0 la transmisión contínua
// si SSPIF=1, terminó la transmisión. SSPIF-> PIR1,3
bit_clear(PIR1,3); // borro el flag SSPIF
}
return(0);
}
//--------------------------------------------------------------
#inline
int Comando_MMC(int _cmd){
int iRespuesta=cmd[2];//0xff;
long lTiempo_fuera=0;
output_low(MMC_CS);
Leer_1Byte_SPI();
Escribir_1Byte_SPI(cmd[_cmd]);
Escribir_1Byte_SPI(0);
Escribir_1Byte_SPI(0);
Escribir_1Byte_SPI(0);
Escribir_1Byte_SPI(0);
Escribir_1Byte_SPI(0x95);
while(iRespuesta==cmd[2]){//0xff){
iRespuesta=Leer_1Byte_SPI();
if(lTiempo_fuera++>500){ break;}
}
return(iRespuesta);
}
//------------------------------------------------------------------------
#inline
int Iniciar_MMC(){
int t;
long lTiempo_fuera=0;
SSPCON1=0b00110010;
// activa spi por hardware, maestro en Fosc/64, reloj idle en alto (CKP=1)
SSPSTAT=0;
//transmisión ocurre en flanco bajada (CKE=0)
output_high(MMC_CS);
delay_us(100); // una especie de power-up timer para la MMC
for(t=0;t<12;t++){
Leer_1Byte_SPI();
}
while(Comando_MMC(0)!=1){
delay_us(100);
if(lTiempo_fuera++>lTimeout){ return(1);}
}
lTiempo_fuera=0;
while(Comando_MMC(1)!=0){
delay_us(100);
if(lTiempo_fuera++>lTimeout){ return(2);}
}
SSPCON1=0b00110010;
// activa spi por hardware, maestro en Fosc/4, reloj idle en alto (CKP=1)
SSPSTAT = 0;
//transmisión ocurre en flanco bajada (CKE=0
output_high(MMC_CS);
return 0;
}
//------------------------------------------------------------
#inline
int Leer_CID(char *sCID){
int t;
long lTiempo_fuera=0;
output_low(MMC_CS);
while(Comando_MMC(3)!=0){
delay_us(100);
if(lTiempo_fuera++>lTimeout){
output_high(MMC_CS);
return(2);
}
}
while(Leer_1Byte_SPI()!=0xFE){};
for(t=0;t<18;t++){
sCID[t]=Leer_1Byte_SPI();
}
output_high(MMC_CS);
Leer_1Byte_SPI();
return 0;
}
//----------------------------------------------------------------
#inline
int Leer_CSD(char *sCSD){
int t;
long lTiempo_fuera=0;
output_low(MMC_CS);
while(Comando_MMC(4)!=0){
delay_us(100);
if(lTiempo_fuera++>lTimeout){
output_high(MMC_CS);
return(2);
}
}
while(Leer_1Byte_SPI()!=0xFE){};
for(t=0;t<18;t++){
sCSD[t]=Leer_1Byte_SPI();
}
output_high(MMC_CS);
Leer_1Byte_SPI();
return 0;
}