Autor Tema: Problema con tarjeta MMC  (Leído 2073 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado elguitre

  • PIC10
  • *
  • Mensajes: 34
Problema con tarjeta MMC
« en: 03 de Febrero de 2006, 14:02:00 »
Hola vi en el foro que algunos de ustedes han trabajado con este tipo de tarjetas (MMC/SD) la verdad yo estoy intentando pero no puedo comunicarme con ella. Me arme un circuito para leerla por el Puerto paralelo de la PC y eso anda bien, el siguiente paso fue tratar de accederla copn un pic pero no logro comunicarme, estoy trabajando con el codigo de la pagina www.microchipc.com pero no me funciona. Alguien tiene algo que ande?? desde ya muchas gracias

Desconectado El_Coach

  • PIC12
  • **
  • Mensajes: 79
RE: Problema con tarjeta MMC
« Respuesta #1 en: 04 de Febrero de 2006, 05:13:00 »
¡Hola!

Supongo que ya leiste entero este hilo:

http://miarroba.com/foros/ver.php?foroid=46840&temaid=4555720

¿Lo intentaste primero con un pic LF?
¿Conseguiste inicializar la tarjeta?
¿Que pic utilizas?

Échale un vistazo a la libreria que posteó el compañero Ankarius, puede ser que te ahorre mucho trabajo.


Un saludo y suerte!
"Hazlo o no lo hagas, pero nunca lo intentes"

Desconectado elguitre

  • PIC10
  • *
  • Mensajes: 34
RE: Problema con tarjeta MMC
« Respuesta #2 en: 04 de Febrero de 2006, 14:29:00 »
Coach: mira estoy trabajando con un 16f877, a 5V ya que no consigo un LF aca en los comercios, el tema es que utilizo un circuito con un par de transistores para adaptar los datos de 3.3 a 5 y de 5 a 3.3 Eso anda, ya que conectando la memoria al puerto paralelo de la PC la puedo leer tranquilamente.

El tema es que nunca usé el SPI del micro y no se bien si ese sera el problema, estoy utilizando el codigo de la pagina www.microchipc.com el cual creo es el que vos usaste pero no consigo inicializar la memoria. deberia tener una respuesta 0x01 a un comando pero siempre llega 0x00 pienso que el problema esta en el uso del hard SPI del micro.

Bueno saludos si seguire intentando y a la espera de algun salvador! Llorando

Desconectado El_Coach

  • PIC12
  • **
  • Mensajes: 79
RE: Problema con tarjeta MMC
« Respuesta #3 en: 05 de Febrero de 2006, 11:33:00 »
Ok, ahora mejor.

Bien, yo intenté utilizar también el SPI por hardware pero me ocurrió lo mismo que a ti. No recibía la respuesta por parte de la tarjeta en la inicialización. Pero con la ayuda de un osciloscopio descubrí que esto no era así. La tarjeta si que respondía con un 0x01 pero el pic no se porqué, siempre recibía 0x00.
Entonces decidí realizar el SPI por software. Y utilizando exactamente el mismo programa, pero con el SPI que yo generé, sí que me funcionó.

Codigo:

////////////////////////////////////////////////////////////////////////////////////////////////
////                                                                  ////
////   mi_SPI.c                                                         ////
////                                                                  ////
////   Librería para generar un bus SPI por software                              ////
////                                                                  ////
////   mi_SPI_WRITE( int valor );            Envía por SPI el byte que se le pasa      ////
////                                                                  ////
////   int   mi_SPI_READ();                  Devuelve el byte leído por SPI            ////
////                                                                  ////
////////////////////////////////////////////////////////////////////////////////////////////////

void mi_SPI_WRITE( int valor )
{
   int cont = 8;
   
   do
   {
      output_low( _SCK );
      delay_us(1);
      if( valor & 0x80 )      // Si es un 1
         output_high( _SDO );
      else               // Si es un 0
         output_low( _SDO );
      valor <<= 1;
      output_high( _SCK );
      delay_us(1);
   } while ( --cont );

   output_high( _SDO );
   delay_us( 8 );
}

int mi_SPI_READ( void )
{
   int cont = 8;
   int valor = 0;

   do
   {
      output_low( _SCK );
      delay_us(1);
      valor <<= 1;
      output_high( _SCK );
      if( !input( _SDI ) )   // Si es un 0
         valor &= 0xFE;
      else               // Si es un 1
         valor |= 0x01;
      delay_us(1);
   } while ( --cont );

   delay_us( 8 );

   return( valor );
}



Recuerda definir al principio del programa los pines _SCK, _SDI, _SDO y _CS, en los pines que vayas a utilizar.

Espero que te sirva Giño

Ya me cuentas... un saludo.
"Hazlo o no lo hagas, pero nunca lo intentes"

Desconectado elguitre

  • PIC10
  • *
  • Mensajes: 34
RE: Problema con tarjeta MMC
« Respuesta #4 en: 05 de Febrero de 2006, 19:41:00 »
Coach mil gracias por el codigo mañana me pongo con eso y te comento las novedades, pero supongo era el mismo problema. Gracias nuevamente y te tengo al tanto de las novedades!!! Saludos desde parana argentina

Desconectado elguitre

  • PIC10
  • *
  • Mensajes: 34
RE: Problema con tarjeta MMC
« Respuesta #5 en: 08 de Febrero de 2006, 09:25:00 »
Coach: como estas, mira te cuento que logre iniciar la memoria con elo SPI por hardware con el codigo tal cual como se baja de microchipc, el problea que tengo ahora es que el compilador no me compila esta parte del codigo

SPI_WRITE(HIGH(varh));

que es ese  HIGH() ? esa parte de codigo es de la escritura de bloques de datos y de la lectura, tuve que ponerla como comentario para que me compile y uso solo la parte de inicializacion, vos pudiste compilar? Saludos

#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use standard_io(b)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

char Keypress=" ";

int mmc_init();
int mmc_response(unsigned char response);
int mmc_read_block(unsigned long block_number);
int mmc_write_block(unsigned long block_number);
int mmc_get_status();



#int_rda
void rda_isr() {
   Keypress=0x00;
   if(kbhit()){
      Keypress=getc();
   }
}



/************************** MMC Init **************************************/
/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */

int mmc_init()
{
int i;
SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
*0x94 |= 0x40;                          // set CKE = 1 - clock idle low
*0x14 &= 0xEF;                          // set CKP = 0 - data valid on rising edge
OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
for(i=0;i<10;i++)                       // initialise the MMC card into SPI mode by sending clks on
{
        SPI_WRITE(0xFF);
}
OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on) tells card to go to spi mode when it receives reset
SPI_WRITE(0x40);                        // send reset command
SPI_WRITE(0x00);                        // all the arguments are 0x00 for the reset command
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95);                        // precalculated checksum as we are still in MMC mode
puts("Sent go to SPI
"Giño;
if(mmc_response(0x01)==1) return 1;     // if = 1 then there was a timeout waiting for 0x01 from the mmc
puts("Got response from MMC
"Giño;
i = 0;
while((i < 255) && (mmc_response(0x00)==1))     // must keep sending command if response
{
        SPI_WRITE(0x41);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);                // all the arguments are 0x00 for command one
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x01);                // checksum is no longer required but we always send 0xFF
        i++;
}
if(i >= 254) return 1;                  // if >= 254 then there was a timeout waiting for 0x00 from the mmc
puts("Got out of idle response from MMC
"Giño;
OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
SPI_WRITE(0xFF);                        // extra clocks to allow mmc to finish off what it is doing
OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)
        SPI_WRITE(0x50);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x02);                // high block length bits - 512 bytes
        SPI_WRITE(0x00);                // low block length bits
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1;
OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
puts("Got set block length response from MMC
"Giño;
puts("Memoria inicializada!!! uijaaa !!
"Giño;

return 0;
}
/************************** MMC Get Status **************************************/
/* Get the status register of the MMC, for debugging purposes */
int mmc_get_status()
{
OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)
        SPI_WRITE(0x58);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);                //
        SPI_WRITE(0x00);                // always zero as mulitples of 512
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
return 0;
}
/************************** MMC Write Block **************************************/
int mmc_write_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);
puts("Write block
"Giño;                // block size has been set in mmc_init()
OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)
        /*SPI_WRITE(0x58);                // send mmc write block
        SPI_WRITE(HIGH(varh));
        SPI_WRITE(LOW(varh));
        SPI_WRITE(HIGH(varl));
        SPI_WRITE(0x00);                // always zero as mulitples of 512
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1;
puts("Got response to write block
"Giño;
SPI_WRITE(0xFE);                        // send data token
for(i=0;i<512;i++)
{
SPI_WRITE(i2c_eeprom_read(HIGH(i),LOW(i)));     // send data
}
SPI_WRITE(0xFF);                        // dummy CRC
SPI_WRITE(0xFF);
if((SPI_READ(0xFF)&0x0F)!=0x05) return 1;
puts("Got data response to write block
"Giño;
OUTPUT_HIGH(PIN_C2); */                   // set SS = 1 (off)
return 0;
}
/************************** MMC Read Block **************************************/
/**** Reads a 512 Byte block from the MMC and outputs each byte to RS232 ****/
int mmc_read_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);/*
OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)
        SPI_WRITE(0x51);                // send mmc read single block command
        SPI_WRITE(HIGH(varh));          // arguments are address
        SPI_WRITE(LOW(varh));
        SPI_WRITE(HIGH(varl));
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1;   // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative)
puts("Got response to read block command
"Giño;
if((mmc_response(0xFE))==1) return 1;   // wait for data token
puts("Got data token
"Giño;
        for(i=0;i<512;i++)
        {
                putc(SPI_READ(0xFF));   // we should now receive 512 bytes
        }
SPI_READ(0xFF);                         // CRC bytes that are not needed
SPI_READ(0xFF);
OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
SPI_WRITE(0xFF);                        // give mmc the clocks it needs to finish off
puts("
End of read block
"Giño;*/
return 0;
}
/************************** MMC get response **************************************/
/**** Repeatedly reads the MMC until we get the response we want or timeout ****/
int mmc_response(unsigned char response)
{
        unsigned long count = 0xFFFF;           // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point
        while(SPI_READ(0xFF) != response && --count > 0);
        if(count==0) return 1;                  // loop was exited due to timeout
        else return 0;                          // loop was exited before timeout
}





void main()
 {
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(RA0_RA1_ANALOG_RA3_REF);
   output_low(PIN_B5);

   enable_interrupts(int_rda);
   enable_interrupts(global);

   printf("
UTN - Facultad Regional Parana
" );
   printf("
 Tecnicas Digitales I
" );
   printf("
 Aprete i para inicializar

" );
   do {




      if(Keypress!=0x00)
      {
         switch(Keypress)
                        {
                           case "i": if (mmc_init()==0)
                                       printf("
 Arranco la memoria  

" );
                                       else  printf("
 No anda la puta madre!

" );
                           break;

                           case "0": output_low(PIN_B5);
                           printf(" 0 - LED Apagado
" );
                           break;

                           case "1": output_high(PIN_B5);
                           printf(" 1 - LED Encendido
" );
                           break;
                        }
         Keypress=0x00;
       }

   } while (TRUE);

 }

Desconectado El_Coach

  • PIC12
  • **
  • Mensajes: 79
RE: Problema con tarjeta MMC
« Respuesta #6 en: 08 de Febrero de 2006, 10:21:00 »
Hola!

Me alegra que lo hicieras funcionar por hardware!!

Mira, cuando haces:

Codigo:

variable = 0xA1EF;
a = HIGH( variable );    // En a tienes 0xA1
b = LOW( variable );    // Y en b tienes 0xEF



Con HIGH asignas la parte alta y con LOW la parte baja de un numero de 16bits.
Creo que tampoco me funcionó así que utilicé:

Codigo:

variable = 0xA1EF;
a = make8( variable , 1 );    // En a tienes 0xA1
b = make8( variable , 0 );    // Y en b tienes 0xEF



Con make8 creas un entero de 8 bits apartir de otro de más, como x ejemplo un int16. Se le pasa el nombre de la variable y el offset, 1 para la parte alta y 0 para la baja.
No se si habrá otra forma más sencilla, pero eso funcionaría.


Salu2 RollEyes
"Hazlo o no lo hagas, pero nunca lo intentes"

Desconectado elguitre

  • PIC10
  • *
  • Mensajes: 34
RE: Problema con tarjeta MMC
« Respuesta #7 en: 08 de Febrero de 2006, 13:41:00 »
Amigo Coach: si la verdad estoy contento por hacerla andar, ahora voy a corregir lo de las direcciones, por que pude escribir y leer la memoria y mirar con el win hex, pero escribia por cualquier lado, ahora arreglo ese tema, espero que quede funcionando a full.

El problema del hard era que el pin SDO del pic estaba conectado a la salida de datos de la memoria y el pic SDI a la entrada de la memoria jaja por eso no se comunicaba

Saludos!Rebotado

Desconectado dopoulo

  • PIC10
  • *
  • Mensajes: 24
RE: Problema con tarjeta MMC
« Respuesta #8 en: 08 de Febrero de 2006, 13:59:00 »
Te había mandado un privado pero ya veo que lo has solucionado
Enhorabuena.
1 saludo.

Desconectado elguitre

  • PIC10
  • *
  • Mensajes: 34
RE: Problema con tarjeta MMC
« Respuesta #9 en: 15 de Febrero de 2006, 07:50:00 »
Dopoulo, gracias por tu ayuda y la de Coach, perdon por no contestar antes, pasa que hace unos dias fue mi cumpleaños y me dedique al festejo y no a la electronica, por eso no habia visto los mensajes. Bueno gracias nuevamente y cuando tenga listo mi proyecto lo comparto con todos los del foro. Saludos