Autor Tema: JM60 y EEPROM por I2C !Funcionando!!  (Leído 12653 veces)

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

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
JM60 y EEPROM por I2C !Funcionando!!
« en: 22 de Noviembre de 2010, 23:09:38 »
Hola a todos!,

Tengo un gran detalle que me tiene mas de 5 días trabajando, ya se me acabo el tiempo y no logre hacerlo trabajar correctamente, por lo cual acudo a ustedes para saber si alguien tenga experiencia con esta practica en los micros Freescale y me pueda guiar.

Estoy intentando implementar el I2C con el JM60. Buscando en la WEB tengo que la AN3291 explica de manera detallada como conectar con una EEPROM por I2C.  Ya logro escribir datos en la EEPROM, pero entre dato y dato me toca implementar un retardo de 3 milisegundos como mínimo para que funcione.. :?

Las funciones que tengo son las siguientes:

Código: C
  1. void IIC_write_byte(UINT16 address, UINT8 data){
  2.   IICC_TXAK = 0;                   // RX/TX = 1; MS/SL = 1; TXAK = 0;
  3.   IICC |= 0x30;                    // And generate START condition;
  4.   //-------start of transmit first byte to IIC bus-----
  5.   IICD = (0xA0);                   // Address the slave and set up for master transmit;
  6.   while(IICS_RXAK);                // check for RXAK;
  7.   while (!IICS_IICIF);             // wait until IBIF;
  8.   IICS_IICIF=1;                    // clear the interrupt event flag;
  9.   //-----Slave ACK occurred------------
  10.   IICD = ((UINT8)(address>>8));    // Send high byte of the word address;
  11.   while(IICS_RXAK);                // check for RXAK;
  12.   while (!IICS_IICIF);             // wait until IBIF;
  13.   IICS_IICIF=1;                    // clear the interrupt event flag;
  14.   //-----Slave ACK occurred------------
  15.   IICD = ((UINT8)address);         // Send low byte of the word address;
  16.   while(IICS_RXAK);                // check for RXAK;
  17.   while (!IICS_IICIF);             // wait until IBIF;
  18.   IICS_IICIF=1;                    // clear the interrupt event flag;
  19.   //-----Slave ACK occurred------------
  20.   IICD = data;                     // Envia Dato a Escribir
  21.   while(IICS_RXAK);                // check for RXAK;
  22.   while (!IICS_IICIF);             // wait until IBIF;
  23.   IICS_IICIF=1;                    // clear the interrupt event flag;
  24.   //-----Slave ACK occurred------------;
  25.   IICC_MST = 0;                    // generate STOP condition;
  26. }


Código: C
  1. UINT8 IIC_read_byte(UINT16 address){
  2.   UINT8 data;
  3.   IICC_TXAK = 0;                    // RX/TX = 1; MS/SL = 1; TXAK = 0
  4.   IICC |= 0x30;                     // And generate START condition
  5.   IICD = (0xA0);                    // Address the slave and set up for master transmits
  6.   while (!IICS_IICIF);              // wait until IBIF
  7.   IICS_IICIF=1;                     // clear the interrupt event flag
  8.   while(IICS_RXAK);                 // check for RXAK
  9.   //-----Slave ACK occurred------------
  10.   IICD = ((UINT8)(address>>8));       // Send high byte of the word address
  11.   while (!IICS_IICIF);              // wait until IBIF
  12.   IICS_IICIF=1;                     // clear the interrupt event flag
  13.   while(IICS_RXAK);                 // check for RXAK
  14.   //-----Slave ACK occurred------------
  15.   IICD = ((UINT8)address);         // Send low byte of the word address;
  16.   while(IICS_RXAK);                // check for RXAK;
  17.   while (!IICS_IICIF);             // wait until IBIF;
  18.   IICS_IICIF=1;                    // clear the interrupt event flag;
  19.   //-----Slave ACK occurred------------
  20.   IICC_RSTA = 1;                    // set up repeated start
  21.   IICD = (0xA1);                    // (slave_address) | (RW = 1)
  22. while (!IICS_IICIF);              // wait until IBIF
  23.   IICS_IICIF=1;                     // clear the interrupt event flag
  24.   while (IICS_RXAK);                // check for RXAK
  25.   //-----Slave ACK occurred------------
  26.   IICC_TX = 0;                      // set up to receive
  27.   IICC_TXAK = 1;                    // acknowledge disable
  28.   data = IICD;                      // dummy read
  29.   while (!IICS_IICIF);              // wait until IBIF
  30.   IICS_IICIF=1;                     // clear the interrupt event flag
  31.   IICC_MST = 0;                     // generate stop signal
  32.   data = IICD;                      // read right data
  33.   return(data);
  34. }

Luego en la función main lo siguiente:

Código: C
  1. IIC_write_byte(0x0000,'E');
  2. delay_ms(3);
  3. IIC_write_byte(0x0001,'R');
  4. delay_ms(3);
  5. IIC_write_byte(0x0002,'N');
  6. delay_ms(3);
  7. IIC_write_byte(0x0003,'E');
  8. delay_ms(3);
  9. IIC_write_byte(0x0004,'S');
  10. delay_ms(3);
  11. IIC_write_byte(0x0005,'T');
  12. delay_ms(3);
  13. IIC_write_byte(0x0006,'O');
  14. delay_ms(3);
  15. IIC_write_byte(0x0007,'.');
  16. delay_ms(3);

Efectivamente se escriben las palabras en la EEPROM, pero los 3 milisegundos no puedo elimnarlos. A que se debe ello?


Ahora, cuando intento leer datos..siempre me llegan ff  :?

Ya pase por este lado donde discuten el tema

Ya revise la AN3291



Busque en CCS como gestiona la EEPROM y encontre esto:

Código: C
  1. void write_ext_eeprom(long int address, BYTE data)
  2. {
  3.    short int status;
  4.    i2c_start();
  5.    i2c_write(0xa0);
  6.    i2c_write(address>>8);
  7.    i2c_write(address);
  8.    i2c_write(data);
  9.    i2c_stop();
  10.    i2c_start();
  11.    status=i2c_write(0xa0);
  12.    while(status==1)
  13.    {
  14.    i2c_start();
  15.    status=i2c_write(0xa0);
  16.    }
  17.    i2c_stop();
  18. }

Lo que encontré extraño y diferente es lo que marque en negrilla, pues si no da ACK la Eeprom, generan Reestart e intentan nuevamente, pero ese procedimiento no lo logre hacer con el JM60, pues el bit de respuesta ACK, siempre se espera a que llegue, no se alguno de ustedes ya implemento esta opción en Codewarrior.



Tienen alguna pista?
« Última modificación: 23 de Noviembre de 2010, 20:39:47 por LABmouse »

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #1 en: 22 de Noviembre de 2010, 23:25:00 »
Hola! Esos 3 milisegundos son necesarios para que la memoria realice la escritura. Por ahi te conviene escribir por páginas, que ocupa el mismo tiempo de escritura ~3ms  ;-)

Hay otras memorias, de Ramtron, con estas no se necesita ese tiempo de escritura.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #2 en: 22 de Noviembre de 2010, 23:34:16 »
Otra cosa, según datasheet este ciclo de escritura puede llegar a 5ms, entonces conviene testear el estado de la memoria antes de enviar otro byte, esto se hace enviando un start, escribiendo la dirección del dispositivo (ej 0xA0) y testeando el bit de ack que devuelve la memoria, cuando sea 0 es que está en condiciones de recibir otro byte.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #3 en: 22 de Noviembre de 2010, 23:44:29 »
Hola amigo Suky,

Pues que tonto soy, no se me dio por leer las indicaciones de tiempo y efectivamente Microchip dice que son 5 milisegundos el ciclo de escritura. (Detalles que con CCS se olvidan y mal acostumbran pero cuando se enfrenta con ANSI-C, debe tenerse en cuenta totalmente)

Seguí tu recomendación de esperar a que la EEPROM me conteste con un ACK para empezar a escribir otra vez, ya te comento como me va. (Me fue mal, no aprendo a discriminar si llega o no el ACK, pues según lo recomendado de Freescale, hay que esperar dentro de un while a que llegue, pero eso no me da la opción a generar un restart e intentar nuevamente a ver si llega el ACK)


Ahora me queda la Lectura que me da siempre FF, ya comento también como sigo con esta pelea.

SALUDOS!


« Última modificación: 22 de Noviembre de 2010, 23:55:39 por LABmouse »

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #4 en: 22 de Noviembre de 2010, 23:57:57 »
Estudie la función read y no veo nada raro, hasta envias el Nack al recibir el byte (Cosa que muchos no implementan  :mrgreen: ) Puede que realmente esté en 0xFF la dirección que lees, por no haberse realizado la escritura correctamente ?



Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #5 en: 23 de Noviembre de 2010, 00:00:57 »
Para verificar que no este en 0xFF, tengo un lector de EEPROM y con el probé que efectivamente si escribe en la memoria... Ta raro, voy a hacerle otro intento.

PD: Ya la escritura esta dentro de las macros que estoy desarrollando para el EFmJM60  :P , esta noche espero terminar y estarán para todos en el FORO!!  :mrgreen:

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #6 en: 23 de Noviembre de 2010, 00:08:19 »
Lograste solucionar el tema del ack? Yo pensaba probar con algo por el estilo:

Código: C
  1. do{
  2.     IICC_TXAK = 0;                   // RX/TX = 1; MS/SL = 1; TXAK = 0;
  3.     IICC |= 0x30;                    // And generate START condition;
  4.     //-------start of transmit first byte to IIC bus-----
  5.     IICD = (0xA0);                   // Address the slave and set up for master transmit;
  6.     while (!IICS_IICIF);             // wait until IBIF;
  7.     IICS_IICIF=1;                    // clear the interrupt event flag;
  8.   }while(IICS_RXAK==1);
  9.   IICC_MST = 0;

Pero esto lo agregaría al iniciar una escritura, así no queda clavado después de enviar un byte a la memoria. Así se sigue con la ejecución del código, y cuando se necesite escribir otro dato, si no paso el tiempo necesario, que compruebe la memoria.  ;-)


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #7 en: 23 de Noviembre de 2010, 00:15:11 »
Pues intente algo parecido, pero no siempre que la abdera IICS_IICIF se activa por fin de envío de dato, esta listo el ACK de la memoria,creo hay que darle un tiempo, y estoy probando esos detalles de espera a ver cuanto mínimo habría que darle.

Saludos!

PD: Definitivamente se hace indispensable un buen analizador lógico USB...Pero quisiera uno que analizara USB también ¿Conocen alguno?

« Última modificación: 23 de Noviembre de 2010, 00:21:19 por LABmouse »

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #8 en: 23 de Noviembre de 2010, 00:23:20 »
Hola,

Pues encontré el motivo de mi mala Lectura, me faltaba una linea en el procedimiento, y ya esta arreglada en la función del primer POST para que quien la necesite, la tenga a la mano.  Me hacia falta esto:

while (!IICS_IICIF);              // wait until IBIF

Cuando enviaba el 3er Byte a la EEPROM.

Lo raro es que toca darle otros 5 milisegundos entre lectura y lectura..  :?

« Última modificación: 23 de Noviembre de 2010, 00:27:06 por LABmouse »

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #9 en: 23 de Noviembre de 2010, 00:35:14 »
Lo raro es que toca darle otros 5 milisegundos entre lectura y lectura..  :?

Eso si que no puede ser. Entre lectura y lectura no hay que esperar nada  :?
No contesto mensajes privados, las consultas en el foro

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #10 en: 23 de Noviembre de 2010, 01:01:05 »
Pues ya esta 100% funcional....

Hay que esperar 5 milisegundos entre escritura y escritura.
No hay que esperar retardo alguno entre lectura y lectura.

En unos minutos montare el resultado para todos, primero voy a pasar a macros las funciones de lectura I2C.

Gracias amigo Suky...El apoyo fue indispensable para lograrlo.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #11 en: 23 de Noviembre de 2010, 09:54:07 »
 :-/ Buenísimo!
No contesto mensajes privados, las consultas en el foro

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #12 en: 23 de Noviembre de 2010, 10:33:52 »
Hola,
Bueno, pues acá les dejo el proyecto completo para que pueda ser probado con el JM60 y el modulo EFmJM60. Los resultados son:

Lectura de memoria EEPROM 24C256.

Link de descarga de proyecto

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #13 en: 23 de Noviembre de 2010, 13:07:30 »
Excelente Ernesto !!!. Lastima que no puede ayudar en nada  :(. Solamente tengo algunos comentarios.

  • Los 5 ms podrias colocarlos dentro de la función de escritura. De esta manera nunca te vas a olvidar de ponerlo
  • Cambiaria algunos tipos de datos, ejemplo long int por dword

Saludos !

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
« Respuesta #14 en: 23 de Noviembre de 2010, 17:34:33 »
Hola,

Amigo RICHI777, 

Citar
Los 5 ms podrias colocarlos dentro de la función de escritura. De esta manera nunca te vas a olvidar de ponerlo
Pues realmente me gustaría implementar mejor la espera de ACK por parte de la EEPROM para así continuar.

Citar
Cambiaria algunos tipos de datos, ejemplo long int por dword
Me puedes indicar por favor ¿cual es la diferencia?..


 

anything