Autor Tema: Inicializacion SD  (Leído 5890 veces)

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

Desconectado arcadi

  • PIC12
  • **
  • Mensajes: 74
Inicializacion SD
« en: 03 de Abril de 2009, 10:40:33 »
Buenas a todos;

estoy haciendo el proyecto de fin de carrera y tengo que trabajar con una SD.
El problema lo tengo cuando inicializo la SD. Es como si se metieran voltages paràsitos:
ya que cuando no hay SD y hago muchos resets en el PIC, alguna vez se inicializa; y cuando
no existe SD pasa igual.

Lo he probado iniciandola con FAT y con mmcsd y nada... Pido si alguien me puede ayudar con
el proyecto, con el Proteus no funciona y por esto lo tengo todo en protoboard.

En el foro de CCS dicen que la libreria mmcsd tiene bugs, pido si alguien puede colgar la libreria:
fat.c y mmcsd.c para poder probar. Tambien os dejo mis librerias, la mmcsd he cambiado el SPi ya
que lo tengo todo por Hard.

Os dejo el programa, las librerias y el esquema del circuito en proteus.


Muchas gracias a todos.
Anglès (Girona)

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Inicializacion SD
« Respuesta #1 en: 03 de Abril de 2009, 16:59:03 »
... Es como si se metieran voltages paràsitos:
ya que cuando no hay SD y hago muchos resets en el PIC, alguna vez se inicializa; y cuando
no existe SD pasa igual.
...

al parecer le hace falta un filtrado al circuito.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado arcadi

  • PIC12
  • **
  • Mensajes: 74
Re: Inicializacion SD
« Respuesta #2 en: 04 de Abril de 2009, 04:51:49 »
¿un filtrado? aun asi no reconoce la Sd... voy a probar mas cosas hoy
Anglès (Girona)

Desconectado arcadi

  • PIC12
  • **
  • Mensajes: 74
Re: Inicializacion SD
« Respuesta #3 en: 04 de Abril de 2009, 05:30:43 »
Estoy buscando en el foro de CCS, y he encontado un error que tengo.

En todos los esquemas que se pueden encontrar (el 85% mas o menos),
meten la salida de datos directamente en el PIC. Es decir, la informacion
SD ---> PIC se hace a 3,3V, y segun el datasheet para detectar un 1 logico
se tiene que hacer a 0,7·Vdd=0,7·5=3,5V (no llego y por esto puede haver
parasitos).

Otra cosa que he encontrado es un bug en el archivo mmcsd.c, depende de
la version del compilador.
Anglès (Girona)

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Inicializacion SD
« Respuesta #4 en: 04 de Abril de 2009, 15:27:26 »
...
En todos los esquemas que se pueden encontrar (el 85% mas o menos),
meten la salida de datos directamente en el PIC. Es decir, la informacion
SD ---> PIC se hace a 3,3V, y segun el datasheet para detectar un 1 logico
se tiene que hacer a 0,7·Vdd=0,7·5=3,5V (no llego y por esto puede haver
parasitos).


si es cierto, porque el pic usa la lógica ttl que reconoce esos niveles de tensión respectivos.
mira en la darasheet de un sd o mmc y entre imagenes hay una donde colocan unos condensadores en los pines de los datos. También es recomendable colocar un condensador de 100nF muy cerca de la alimentación de la SD (si es posible soldarlo directamente en los pines del zócalo)


...
Otra cosa que he encontrado es un bug en el archivo mmcsd.c, depende de
la version del compilador.

yo probé ese driver y me dió problemas, como es muy genérica no me tomé el tiempo para averiguar el porque no me funcionaba, pero hay algo que debes tener en cuenta, la frecuencia de inicialización debe tener un reloj SPI menor o igual a 400Khz.

hay gente en el forum de ccs que asegura que incluso con 800Khz funciona, pero no hay garantias.






La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado sony

  • PIC10
  • *
  • Mensajes: 23
Re: Inicializacion SD
« Respuesta #5 en: 04 de Abril de 2009, 20:48:22 »
aqui esta um exemplo a funcionar .   

http://www.dharmanitech.com/

Desconectado PHLAKO

  • PIC10
  • *
  • Mensajes: 49
Re: Inicializacion SD
« Respuesta #6 en: 19 de Abril de 2009, 23:11:21 »
Hola arcadi y demas foreros,

Estoy tambien empezando con la comunicacion PIC -> MMC-SD, pero ya empezando no doy con el algoritmo de calculo del CRC7, tanto asi, k ya llevo 5 dias rompiendome la cabeza....pues alguien seria tan amable de explicarme como diablos se llega al valor CRC=4A, probe con la tecnica de ir dividiendo y bajando los unos o ceros, tambien probe rotando y metiendo bits a bits, haciendo la opracion XOR cuando salia por la izquierda un b it uno, etc. He buscado un monton, y lo que no quiero hacer es agarrar un codigo y usarlo sin saber la logica de este, alguien que me de una mano, les dejo una foto donde ponen el misterioso diagrama que no puedo llevar a un algoritmo, del primer ejemplo se desprende el valor de CRC = a 4A.



A ver si puedo avanzar para colaborar con el amigo del proyecto :)

saludos

chaos:)
SIEMPRE TE RECORDARE AMADO Y FIEL COMPAÑERO "LOBO"


Desconectado arcadi

  • PIC12
  • **
  • Mensajes: 74
Re: Inicializacion SD
« Respuesta #8 en: 20 de Abril de 2009, 04:58:04 »
Bunas a todos,

yo estoy utilizando la cuminicacion SPI, y los comandos los saco de http://www.forosdeelectronica.com/about13868.html .
El problema que tengo cuando lo hago paso a paso, es que en proteus me va bien, con la comanda CM0 y CM41; pero en
protoboard no.


---------------------------DE OTRA PARTE--------------------------------------

Estoy en el hilo http://www.todopic.com.ar/foros/index.php?topic=18383.320 , resulta que tengo las librerias fat.c y mmcsd.c
y si me van bien tengo ya medio proyecto hecho... Pero resulta que trabajo con CCS, y PICMouse ha hecho correr estas librerias
correctamente con C18.

Ahora mismo estoy intentando linkar C18 con las librerias de la CCS.


Espero haberte ayudado PHLAKO.



Muchas gracias a todos

Anglès (Girona)

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Inicializacion SD
« Respuesta #9 en: 20 de Abril de 2009, 13:08:53 »
Hola arcadi y demas foreros,

Estoy tambien empezando con la comunicacion PIC -> MMC-SD, pero ya empezando no doy con el algoritmo de calculo del CRC7, tanto asi, k ya llevo 5 dias rompiendome la cabeza....pues alguien seria tan amable de explicarme como diablos se llega al valor CRC=4A, probe con la tecnica de ir dividiendo y bajando los unos o ceros, tambien probe rotando y metiendo bits a bits, haciendo la opracion XOR cuando salia por la izquierda un b it uno, etc. He buscado un monton, y lo que no quiero hacer es agarrar un codigo y usarlo sin saber la logica de este, alguien que me de una mano, les dejo una foto donde ponen el misterioso diagrama que no puedo llevar a un algoritmo, del primer ejemplo se desprende el valor de CRC = a 4A.



A ver si puedo avanzar para colaborar con el amigo del proyecto :)

saludos

chaos:)


Phlako agregué la rutina de CRC al post que Nocturno te menciona porque leí que hacía falta. Probé calculando los ejemplos que figuran en la imágen que posteaste y el algoritmo functiona.

Te recuerdo que el CRC7 que necesitás toma como variable de entrada el cálculo del CRC anterior, y debés someter a los 5 bytes(uno por uno) al cálculo del CRC. Por ejemplo en el primero sería:

CRC1 = value= 01000000 poly=0x48 enter_value=0x00 exit_value=0x00
CRC2 = value= 00000000 poly=0x48 enter_value=CRC1 exit_value=0x00
CRC3 = value= 00000000 poly=0x48 enter_value=CRC2 exit_value=0x00
CRC4 = value= 00000000 poly=0x48 enter_value=CRC3 exit_value=0x00
CRC5 = value= 00000000 poly=0x48 enter_value=CRC4 exit_value=0x00

Si hacés todo bien deberías llegar al 0x4C que el datasheet demuestra.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado PHLAKO

  • PIC10
  • *
  • Mensajes: 49
Re: Inicializacion SD
« Respuesta #10 en: 21 de Abril de 2009, 20:13:09 »
Hola foreros,

Perdon por no postear ayer (mi jefe no me da respiro, y si me ve posteando me mata).

Gracias por todos los datos........pero aun sigo con el problema aquel.

BrunoF, en el link que puso el amigo Nocturno, vi que calculaste un CRC y despues lo incrementaste en uno, me imagno que fue un error ya que ahi mismo pusiste otro ejemplo donde no se incrementaba(A001).  Tambien note que un valor decimal de P(2) = 2·16 + 2·15 + 2·2 + 1 = 28005 deberia ser 98309, si estoy equivocado en la apreciacion, me corrigen, ya que tengo un lio en la cabeza a estas alturas...como quede enredado, opte por lo sano. Se supone que para iniciar la tarjeta SD en modo SPI, debe uno mandarle un tren de pulso, despues mandar 40 00 00 00 00 + el byte que contiene el CRC7, pues bien el valor del CRC7 es 4A, que va en el lado de mayor peso en ese byte, el bit0 es siempre es uno, eso sale en el data, en la foto que puse mas arriba (no se como calculaste ese 4C, cumpa BrunoF). asi el ultimo byte es 10010101, que se lee 95 en exa. Asi todo lo que hay que transmitir para que quede la SD operativa es 40 00 00 00 00 95 , donde se queda uno esperando la respuesta (R1=0x01), bien me puse a hacer esto, ya que no doy con el calculo de CRC7, teniendo en cuenta que al ser activada la SD en modo SPI, solo el primer comando va con CRC7, de ahi en adelante uno le tiene que activar si quiere usar o no el CRC, asi esque lo dejare asi hasta que pueda realizar las operaciones basicas.

Ahora el bicho ese me responde con un 0x05 (R1), si me responde en formato SPI, imagino que estara en modo SPI. Al mandarle el 40 00 00 00 00 95, logro leer 0x05 0xFF y 0x01 es este unltimoo valor de R1 el que me interesa, imagino que si leeo 0xFF es solo porque la SD se esta tomando un tiempo para procesar, y lo que se lee es el valor del estado en alto del Data Out de la memo. El leer el 0x05 efinitivamente no se por que sucede. Yo solo lo tengo en un loop leyendo hasta que el valor de lectura sea 0x01..........despues mando 41 00 00 00 00 xx, que se utiliza para verifiar el estado de SD, esta respuesta debe ser R1=0x00, que nos indica que estaria lista para operar, en este caso tambien leo 0x05 toooodo el rato. y ahi es donde estoy pegado.

Luego pongo el codigo..........a ver que me dicen

los pulsos estan a 625Khz.

arcadi: te funciono todo en C18? :lol:


Perdon si no fue muy bien redactado, ya son las 19:12Hrs, y aun estoy en mi trabajo dandole vueltas a esto :shock:

Saludos,

chaos :)

SIEMPRE TE RECORDARE AMADO Y FIEL COMPAÑERO "LOBO"

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Inicializacion SD
« Respuesta #11 en: 21 de Abril de 2009, 20:31:33 »
Hola el manejo de CRC en una memoria SD/MMC es opcional, solo lo necesita el primer comando, despues enviando cualquier cosa funciona. Te paso un link de algo que implemente y funciona bien.

http://www.todopic.com.ar/foros/index.php?topic=23459.0

Saludos !

Desconectado PHLAKO

  • PIC10
  • *
  • Mensajes: 49
Re: Inicializacion SD
« Respuesta #12 en: 26 de Abril de 2009, 01:29:36 »
Hola a todos, leyendo mucho por aqui y por aca, encontre harta diferencia entre un par de SD de distintas marcas. La que ha mostrado señales de vida es una memoria SD kingston de 1 GB. Con una Sandisc, no hubo caso. No fue posible arrancar ninguna de las dos, a menos que se envie el CRC7 del CMD0 y CMD1. Para la gente que pueda estar experimentando con estas memorias y no puede pasar del CMD0 con respuesta valida, les recomiendo probar con el CRC7 en los dos primeros comandos. El codigo lo deje en mi trabajo, a si es que mas rato cuelgo unas fotos que tome del osciloscopio.

Ojala alguien este tambien con este tema, para que hagamos un "paso a paso" de la operacion basica con SD, ya que en ningun lado aparece claro.

Saludos :)

chaos :)



COdigo:

#include <p18f452.h>
#include <spi.h>
#include <usart.h>
#include <delays.h>
#include <adc.h>
#include <stdlib.h>
#include <string.h>

#pragma config OSC = HS  // xtal=10Mhz
#pragma config OSCS = OFF
#pragma config PWRT = ON
#pragma config BOR = OFF //brown-out reset, BORV = 45 brown-out voltaje (4.5v)
#pragma config WDT = OFF //WDTPS = 1, postscaler 1:1
#pragma config CCP2MUX = OFF
#pragma config LVP = OFF,DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
#pragma config EBTRB = OFF


//********* PROTOTIPOS DE FUNCION ****************

// GENERAL
void Configuracion_Mcu(void);

// USART
void Verificar_DATO_RX(void);

// MMC
void Inicializacion_MMC_en_Modo_SPI(void);



//******* DEFINICION DE VARIABLE *****************

// GENERAL
unsigned char a;
unsigned long b;

// USART
unsigned char DATO_TX;
unsigned char DATO_RX;

// MMC
#define MMC_CS LATDbits.LATD3          // chip selec en RD3

//************************************************
//*********   INTERRUPCION  **********************
void rx_handler (void);

#pragma code rx_interrupt = 0x08
void rx_interrupt (void)
{
   _asm goto rx_handler _endasm
}
#pragma code
#pragma interrupt rx_handler
void rx_handler (void)
{
   DATO_RX = ReadUSART();
   Verificar_DATO_RX();
}   

//*******  FIN INTERRUPCION  *********************
//************************************************


//************************************************************
//*****************  PRINCIPAL  ******************************

void main(void)
{
   Configuracion_Mcu();

   while(1)
   {
      while(BusyUSART());
   putrsUSART("\n\r\n\rINICIANDO SD\n\r\n\r");

   Inicializacion_MMC_en_Modo_SPI();
   }
}

//************************************************************
/////////////////////  FUNCIONES  ///////////////////////////*
//************************************************************

//************************************************************
//**************  Inicializacion_MMC_en_Modo_SPI  ************   

void Inicializacion_MMC_en_Modo_SPI(void)
{
OpenSPI(SPI_FOSC_64, MODE_11, SMPMID);

MMC_CS = 1;

   for(a=0;a<10;a++)         //se envian 80 pulsos por la linea de clock
   {                     //el manual dice 74, pero asi parece funcionar de todas formas
   putcSPI(0xFF);            //los pulson viajan a 165 KHz.
   }

MMC_CS = 0;                  //habilita SD.

a=0x00;                     //cero en nuestra variable, solo para estar seguros que no es 0x01.

   while (a!=0x01)
   {
   Delay10TCYx(10);

   WriteSPI(0x40);            //se envia comando CMD0, resetea SD y deja en modo SPI IDLE
   WriteSPI(0x00);            //solo queda operativa para algunos comandos.
   WriteSPI(0x00);
   WriteSPI(0x00);
   WriteSPI(0x00);
   WriteSPI(0x95);            //CRC7 calculado previamente (esto aparece en la ficha tecnica).
   
   WriteSPI(0x55);            //8 clocks despues de cada comando. Como lo que cuentan son los pulsos
                        //de reloj, se envia un 0x55, para una facil identificacion del dato
                        //mediante un osciloscopio.
   a=ReadSPI();

      while(BusyUSART());      //bandera, se visualiza en la terminal, las veces que se intento leer
   WriteUSART('/');         //la respuesta al comando "CMD0".
   }

WriteSPI(0xFF);               //pulsos necesarios para que la SD termine con algun procedo pendiente.

MMC_CS = 1;                  //deshabilita SD.

   while(BusyUSART());
putrsUSART("MODO SPI LISTO, ESTADO=IDLE\n\r\n\r");   //bandera, avisa que el CMD0 fue aceptado por la SD.

//-----------------------

MMC_CS = 0;

a=0xFF;                     //unos en nuestra variable, solo para estar seguros que no es 0x00.

   while(a!=0x00)
   {
   Delay10TCYx(10);
   
   WriteSPI(0x41);            //se envia comando CMD1, deja SD lista para recibir resto de comandos.
   WriteSPI(0x00);
   WriteSPI(0x00);
   WriteSPI(0x00);
   WriteSPI(0x00);
   WriteSPI(0xF9);            //segun manual todos los comandos deben llevar CRC7, pero si envio otro dato,
                        //la señal se vuelve inestable y ocurren lecturas en tiempos indeseados.

   WriteSPI(0x55);            //idem
   
   a=ReadSPI();

      while(BusyUSART());      //bandera, se visualiza en la terminal, las veces que se intento leer
   putcUSART('*');            //la respuesta al comando "CMD1"
   }
   
WriteSPI(0xFF);               //idem

MMC_CS = 1;

   while(BusyUSART());
putrsUSART("TARJETA OPERATIVA\n\r\n\r");   //bandera, avisa que el CMD1 fue aceptado por la SD.

//-----------------------

MMC_CS = 0;

a=0xFF;                     //unos en nuestra variable, solo para estar seguros que no es 0x00

   while(a!=0x00)
   {
   Delay10TCYx(10);   

   WriteSPI(0x50);            //se envia CMD16 , longitud de bloque.
   WriteSPI(0x00);
   WriteSPI(0x00);
   WriteSPI(0x02);
   WriteSPI(0x00);
   WriteSPI(0x00);            //para algunosvalores como por ejemplo 0xFF, la SD no envia respuesta
   
   WriteSPI(0xFF);            //idem

   a=ReadSPI();

      while(BusyUSART());         //bandera, se visualiza en la terminal, las veces que se intento leer
   putcUSART('-');               //la respuesta al comando "CMD16"
   }   

WriteSPI(0xFF);

MMC_CS = 1;

   while(BusyUSART());
putrsUSART("BLOQUES DE 512 BYTES\n\r\n\r");

}

//************************************************************
//************** FUNCION Configuracion_Mcu *******************   

   void Configuracion_Mcu(void)
   {
   TRISA = 0b11111111;      // A7=, A6=, A5=, A4=, A3=, A2=, A1=, A0=
   TRISB = 0b11011111;      // B7=, B6=, B5=, B4=, B3=, B2=, B1=, B0=
   TRISC = 0b10010111;      // C7=RX , C6=TX, C5=SDO, C4=SDI, C3=SCK, C2=, C1=, C0=
   TRISD = 0b11110011;      // D7=, D6=, D5=, D4=, D3=#CS_MCC, D2=E2P_CS, D1= , D0=
   TRISE = 0b11111111;      // E7=, E6=, E5=, E4=PSPMODE, E3=, E2=
                     // E1=, E0=
   PORTA = 0b00000000;
   PORTB = 0b00000000;
   PORTC = 0b00000000;
   PORTD = 0b00000000;
   PORTE = 0b00000000;
   
   LATA = 0X00;
   LATB = 0X00;
   LATC = 0X00;
   LATD = 0X00;
   LATE = 0X00;

//**************
   MMC_CS = 1;                        // MMC Deshabilitada
//*************

// CONFIGURACION INTERRUPCIONES

   PIE1bits.RCIE = 1;                  // habilita INTERRUPCION POR RECEPCION
   RCONbits.IPEN = 1;                  //se habilita modo prioridad de interrupciones
   IPR1bits.RCIP = 1;                  //interrupcion por recepcion = alta prioridad
   INTCONbits.GIEH = 1;
   PIR1bits.RCIF = 0;

// CONFIGURACION USART

   OpenUSART(USART_TX_INT_OFF &         // USART para 9.6K baudios
           USART_RX_INT_ON &
           USART_ASYNCH_MODE &
           USART_EIGHT_BIT &
           USART_CONT_RX &
           USART_BRGH_LOW,64);
   }

//************************************************************
//************* FUNCION Verificar_DATO_RX ********************
   void Verificar_DATO_RX(void)
   {
      if (DATO_RX==0x31)   //banderade control externo, mediante HyperTerminal
      {
      //sin actividad, por entrada de dato USART
      }
   }

//// FIN //////

detalle del CMD1 =  41 00 00 00 00 F7 + 55 + ReadSPI









Detalle de la respuesta al CMD1, esta es R1 = 00



Claramente se ve una lectura de 0x00 en el ultimo tren de pulsos(estos correspomden al ReadSPI)


Aqui se ve que lee 0xFF al ejecutar ReadSPI, esto ocurre porque la SD no estaba lista para enviar los datos.


El codigo esta hecho de la manera mas sencilla posible, sin utilizar funciones avanzadas, asi todos lo pueden seguir, me incluyo yo, que no manejo mucho "C" ya que he migrado desde ASM, hace poco mas de un mes.

Ojala sigan el hilo, por mi parte hoy vere si puedo escribir en la SD.

Saludos,

chaos:)


« Última modificación: 27 de Abril de 2009, 09:55:09 por PHLAKO »
SIEMPRE TE RECORDARE AMADO Y FIEL COMPAÑERO "LOBO"