Saludos
Todavia trabajando con la memoria sd tratando de ponerla al pelo, pero no he podido ponerla a funcionar bien, el leido el artículo del compañero Suky una y tras vez buscando el posible error (aunque he encontrado ya varios) , todavia sigo buscando en mis rutinas y nada no se que pueda pasar

.
El programa debe hacer lo siguiente:
Al inicio la memoria debe inicializar en modo SPI para cual tengo un rutina que creo ya funciona.
y es la siguiente:
int init_mmc()
{
SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16 | SPI_XMIT_L_TO_H);
OUTPUT_HIGH(PIN_C2);
for(i=0; i<20; i++)
{
SPI_WRITE(0xFF); // espero a que se inicialice la memoria que van desde 8 a 10 pulso del reloj
}
OUTPUT_LOW(PIN_C2); // Activo la targeta
for(i=0; i<20; i++)
{
SPI_WRITE(0XFF); // espero a que se inicialice la memoria que van desde 8 a 10 pulso del reloj
}
SPI_WRITE(0x40);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95); // Comando CMDO datos a enviar
if(mmc_respuesta(0x01)==1)
{
return 1; // Error en memoria por que se supero el tiempo
}
OUTPUT_HIGH(PIN_C2);
return 0;
}
Dentro de esta rutina hay otra rutina que se llama mmc_respuesta(espera) que tiene como parámetro la variable espera y unsigned char (0 hasta 255 sin signo), lo que hace esta rutina es verificar la respuesta de la memoria ante un comando (llamese CMD0, CMD16 etc) es decir, espera el R1 y lo compara con la respuesta adecuada. Esta rutina es general para todas.
Y es la siguiente: Con alguna modificaciones que he hecho.
int mmc_respuesta(unsigned char respuesta)
{
unsigned long espera = 0xFFFF;
while(SPI_READ(0xFF) != respuesta && espera> 0)
{
espera= espera - 1;
}
if(espera==0)
{
return 1; // se ha superado el tiempo
}
else
{
return 0;
}
}La que sigue se llama inicializacion_mmc() y lo que hace esta rutina es inicializar la memoria para quedar lista para escritura y lectura de un bloque de 512 bytes, en esta rutina se envian los comandos CMD1, y CMD16 la configuración de CMD16 se hace de la siguiente forma se envia el comando (0x50, 0x00, 0x00, 0x02, 0x00, 0xFF) en el 4 byte se pone 0x02 para configura el bloque a 512 bytes que es equivalente en hex 0x200 y siempre en multiplos de este número. Lo siguiente es el código.
int inicializacion_mmc()
{
OUTPUT_HIGH(PIN_C2);
for(i=0; i<16; i++)
{
SPI_WRITE(0xFF);
}
OUTPUT_LOW(PIN_C2);
{
SPI_WRITE(0xFF);
}
i = 0;
do
{
SPI_WRITE(0x41); // Envia comando hasta que de la respuesta y hasta que se cumpla el tiempo
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // Secuencia del comando CMD1
i= i + 1;
}
while(i<250 && mmc_respuesta(0x00)==1);
if(i==250)
{
return 1; // si se supera el tiempo de respuesta no se ha inicializado bien la targeta
}
OUTPUT_HIGH(PIN_C2);
for(i=0; i<16; i++) // Alguno cloks para estabilizar la comunicación
{
SPI_WRITE(0xFF);
}
OUTPUT_LOW(PIN_C2);
for(i=0; i<16; i++)
{
SPI_WRITE(0XFF);
}
SPI_WRITE(0x50);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x02);
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // Comando CMD16 para configurarlo de 512 bytes
if(mmc_respuesta(0x00)==1)
{
return 1; // se ha inicializado incorrectamente
}
OUTPUT_HIGH(PIN_C2);
return 0; // se ha inicializado correctamente
}
La siguiente rutina escribe un bloque de 512 bytes segun las especificaciones de la targeta. En esta rutina escribo en el bloque número 2 el valor de 0x17 que es el envio en el bucle de 512 bytes y espero la respuesta de la memoria que debe ser 0x05, para lograr este valor leeo la respuesta de la memoria y hago una mascara con 0x0F para sólo tener en cuenta los primero 4 bits, pero ocurre algo que no se que pueda ser siemple la operación de la mascara es decir
(resp&0x0f=!0x05)siempe está operación lógica me da 0x01 y no se porque lo he revisado una y otra vez no se pueda pasar

.
El código es el siguiente de la rutina que escribe un bloque de 512 bytes en la memoria sd.
int mmc_escribir_bloque()
{
resp = 0;
OUTPUT_HIGH(PIN_C2);
for(i=0; i<16; i++)
{
SPI_WRITE(0xFF); // Unos cuantos ciclos del reloj
}
OUTPUT_LOW(PIN_C2);
for(i=0; i<16; i++)
{
SPI_WRITE(0xFF); // Espero a que se estabilice la memoria
}
SPI_WRITE(0x58);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x02);
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // Comando CMD24 pero escribé en el segundo bloque 0x200
if((mmc_respuesta(0x00))==0x01) // Espero la respuesta RB1
{
return 1; // no respondio correctamente la memoria
}
SPI_WRITE(0xFE); // Envio el token de inicio
for(i=0; i<512; i++)
{
SPI_WRITE(0x17); // Escribó 512 % que en hex es 0x25
}
SPI_WRITE(0xFF);
SPI_WRITE(0xFF); // espero ha que se estabilice o envio 2 CRC
i=0;
do
{
resp = SPI_READ(0xFF);
i=i+1;
}
while(i!=200 && resp==0xFF);
if(i==200) // Se ha superado el tiempo
{
return 1;
}
if((resp&0x0F)!=0x05)
{
return 1; // No se escribio correctamente el bloque de 512 bytes dirente de 00101
}
OUTPUT_HIGH(PIN_C2);
return 0;
}
y por ultimo pongo la rutina principal que lo único que hace es decir si hubo error o todo bien a la hora de la respuesta de la memoria frente a un comando, es decir, por ejemplo responde si estuvo bien la escritura o si hubo un error, lo mismo es para la demás rutinas. Hago una aclaración cuando la rutina retorna "1" hubo un error y cuando retorna un "0".
Acá el código del main.
void main()
{
int lectura;
set_tris_c(0x93);
disable_interrupts(global);
retorno = init_mmc();
if(retorno==0x01)
{
printf("Error en memoria");
}
else
{
retorno = inicializacion_mmc();
if(retorno==0x01)
{
printf("error");
}
else
{
retorno=mmc_escribir_bloque();
if(retorno==0x01)
{
printf("No se pudo escribir el bloque\r");
}
else
{
printf("Escritura realizada");
}
}
}
while(;)
}
No se si ire por mal camino o tendré mal plateado el programa.
Bueno compañeros espero que me puedan ayudar ya que no he encontrado el posible error no se si estoy inicilizando mal la memoria, oh hay algún problema de programación o lógico o de configuración o de hardware etc.
Agradesco al compañero Suky ya que me ha asesorado y me ha aclarado muchas dudas con mucha paciencia, y gracias a él he podido avanzar con problemas pero lo he hecho.

Acá dejo un artículo que encontre es de un dispositivo o mejor dicho un electrocardiograma muy interesante la parte matemática (por si alguién se le mide

) pero lo que me interesa es que en este proyecto también utilizaron una memoria mmc para almacenar los datos del sensor y lo que más me llamo la atención es que está programada en el esamblador.

Saludos.