TODOPIC

Otros Microcontroladores / Dispositivos programables => Microcontroladores ARM => Mensaje iniciado por: LABmouse en 22 de Noviembre de 2010, 23:09:38

Título: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: LABmouse 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 (http://forums.freescale.com/t5/8-Bit-Microcontrollers/AN3291-oddity-problems-with-I2C-device-on-QG8/td-p/11355/page/3)

Ya revise la AN3291 (http://www.google.com.co/url?sa=t&source=web&cd=1&ved=0CBcQFjAA&url=http%3A%2F%2Fwww.freescale.com%2Ffiles%2Fmicrocontrollers%2Fdoc%2Fapp_note%2FAN3291.pdf&ei=fyXrTIzKLoP7lwfIqbB4&usg=AFQjCNHuZNrIJklK3e4w0cTUcy2VwXVGEg)



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?
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: Suky 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!
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: Suky 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!
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: LABmouse 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!


Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: Suky 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!
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: LABmouse 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:
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: Suky 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!
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: LABmouse 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?

Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: LABmouse 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..  :?

Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: Suky 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  :?
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: LABmouse 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.
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: Suky en 23 de Noviembre de 2010, 09:54:07
 :-/ Buenísimo!
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: LABmouse 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.
(http://img146.imageshack.us/img146/2083/datos.gif)

Link de descarga de proyecto (http://img146.imageshack.us/img146/2083/datos.gif)
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: RICHI777 en 23 de Noviembre de 2010, 13:07:30
Excelente Ernesto !!!. Lastima que no puede ayudar en nada  :(. Solamente tengo algunos comentarios.


Saludos !
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: LABmouse 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?..
Título: Re: JM60 y EEPROM por I2C no logro hacer que funcione perfecto...
Publicado por: RICHI777 en 23 de Noviembre de 2010, 17:51:36
Hola Ernesto, es una cuestión de costumbre, yo defino un archivo con tipos y lo uso de la sgte manera.

unsgined char --> byte
unsigned short int -> word
unsigned long --> dword

Casi no uso tipos signeados, en micros de 8 bits es bastante costoso.

Saludos !
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: facundo_10 en 22 de Julio de 2011, 12:19:00
Cual es tu codigo de inicializacion para el i2c ?

Estas usando las interrupciones ?

 while (!IICS_IICIF);             // wait until IBIF;13.  IICS_IICIF=1;   ??

Estoy haciendo algo muy parecido, y tu codigo me va a venir al pelo
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: LABmouse en 25 de Julio de 2011, 09:41:45
Hola facundo,

Yo no uso las interrupciones, pero como si así fuera pues espero la activación de las banderas que indican fin de procesos. como Start, Restart, Write, etc.

Si quieres ver el código del I2C en el proyecto, debes abrir la hoja EFmJM60_stack.h

Saludos!

Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: elotrogonzalo en 12 de Marzo de 2014, 11:16:56
Hola LABmouse, muy buena éstas rutinas!, che podrías subir el proyecto en un zip por que se cayó el link donde pusiste "Link de descarga de proyecto". Espero se pueda! Saludos y muchas gracias!
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: LABmouse en 26 de Mayo de 2014, 11:29:45
Hola elotrogonzalo,

De este LINK puedes descargar todos los proyectos que alcance a desarrollar para el JM6o de Freescale.

http://www.octoplus.com.co/tienda/?wpdmact=process&did=Ny5ob3RsaW5r
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: kevin123 en 03 de Mayo de 2015, 17:56:28
podrias subir el link  del proyecto :)
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: kevin123 en 03 de Mayo de 2015, 17:57:40
podrias subir el link del proyecto  ((:-))
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: LABmouse en 17 de Mayo de 2015, 21:38:06
Para el MPR121.. es I2c por ello es facil adaptarlo para la EEPROM

https://www.dropbox.com/s/wbiimu1j6u9rrys/Proyectos%20GUIA%20JM60.rar?dl=0
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: elotrogonzalo en 04 de Junio de 2015, 21:27:35
LABmouse podrías subir nuevamente el link del proyecto por que están caídos. Quería implementar el i2c por módulo como está hecho aquí por que siempre uso un i2c por soft que andan bien pero....bueno quería tenerlo andando por el modulo también. Muchas gracias!. Saludos.
Título: Re: JM60 y EEPROM por I2C !Funcionando!!
Publicado por: LABmouse en 14 de Junio de 2015, 19:50:59
descarga los proyectos guia que están en esta pagina... en eso esta el ejemplo de I2C

http://www.octoplus.com.co/tienda/como-crear-un-proyecto-con-antmini-jm60-codewarrior-v10-0/