[I2C] Sólo escritura.

888 views
Skip to first unread message

Democrito

unread,
Sep 6, 2019, 5:12:18 AM9/6/19
to FPGAwars: explorando el lado libre
Hola!

Tengo un AD5280 y se comunica a través del protocolo I2C. Es un potenciómetro digital que soporta hasta 15 voltios en los extremos del susodicho; eso sí, como le pase una corriente mayor de 5mA se quema, no es para ponerlo como un potenciómetro normal, sino más bien para usarlo con amplificadores operacionales. Para evitarme accidentes, en las pruebas que le hice a ese integrado sólo uso el óhmetro (téster puesto en ohmios).

Total, que con Arduino hace tiempo que lo hice funcionar y me apetecía ver si podía conseguir lo mismo con una FPGA. Cuando recopilé información sólo vi ejemplos para lectura del I2C, pero en este caso necesitaba escribir. He diseñado un circuito que permite escribir mediante el protocolo I2C. Está basado completamente en registros de desplazamientos. Para evitar complicarme la vida no he sido nada eficiente en el diseño, es un total desperdicio de flip-flops, porque incluso para crear la señal de reloj SCL tb uso flip-flops pre-configurados. Pero... no sé, funciona de maravilla. La premisa que tenía en la cabeza era que fuese modular, para que cualquiera lo pudiese adaptar a sus necesidades de forma rápida y sencilla. Pongo un esquema de ejemplo y luego comento cómo adaptarlo para otros casos:

FPGA_i2c_only_write.PNG

El AD5280 necesita 3 bytes para hacerlo funcionar. Siempre se cumple en todos los casos que el primer byte es de dirección, para este caso es 44 en decimal. El segundo byte es de control, es simplemente algo particular de este chip de cómo se cablee y en mi caso es un valor fijo que vale 16 en decimal. Y el tercer byte es el dato a enviar, que representa una resistencia con valor de 0 hasta 255. Si le envío 0, me da una resistencia mínima que en este caso es de 190 ohmios, si le envío 255 me da la resistencia máxima, que en mi caso es de 20K (hay chips de la misma familia con otros valores máximos), y si pongo otro valor, me da la resistencia correspondiente a ese valor enviado.

¿Cómo adaptarlo para otros casos?

Es muy sencillo. Pero antes explico lo que hace cada módulo, y sabiendo eso se puede aplicar a cualquier tipo de comunicación que sólo sea necesario escribir (recuerda que no puede leer). Doy por hecho que se tiene unos conocimientos mínimos del protocolo I2C.

1.) El módulo "Address" le ponemos la dirección del chip con el que queremos que se comunique. Por dentro ya lleva incluido la secuencia de "Start". Este módulo es la "cabeza del dragón".

2.) "Data" es un byte genérico para enviar. En mi caso es un byte de control.

3.) "Data Stop" es otro byte de información, pero ya lleva incluido la secuencia de "Stop".

Ahora vamos a imaginar varios casos, para comprender cómo montarlos.

Imagina que tenemos un chip que necesita un byte de dirección y 4 bytes de información, entonces construimos de la siguiente manera, ponemos los módulos siguientes:

Address + Data + Data + Data + Data Stop.

Siempre ha de terminar con un módulo "Data Stop".

Ahora imagina que cierto chip sólo necesita un byte de información; ponemos los siguientes módulos:

Address + Data Stop.

A partir de estos dos sencillos ejemplos podemos generalizar para cualquier caso que necesitemos. La cabeza siempre es Address, y la cola siempre es Data Stop.

  • El conexionado es muy simple, van en cascada. La patilla "sod" (serial output data) se conecta con "sid" (serial input data) del siguiente. Lo mismo para "sop" (serial output pulse) va conectada con "sip" (serial input pulse) del siguiente módulo.

  • Todos están conectados a "shift", que es el reloj común para los registros de desplazamientos internos que lleva cada módulo. Necesita tomar la frecuencia a la que funciona el I2C y hemos de pillar los tics de subida y de bajada de dicha frecuencia. Este chip funciona a 400KHz, pero si se le pone menos funciona igual de bien.

  • Por último tenemos la patilla "ld" (load) que hace la carga de los datos cada vez que reciba un tic. En este ejemplo lo hace a través del módulo de comunicación serie.
Como podéis comprobar, una vez que se le pilla la lógica es como jugar a los trenes, donde cada byte es un vagón y es fácimente adaptable a cualquier I2C donde necesitemos solamente escribir. Nótese, que en el módulo "address" existe una patilla llamada "RW", pero en realidad esa patilla siempre ha de ser 0, porque no puede hacer lecturas.

Adjunto los ICEs. Es un ejemplo y los módulos los he zipeado.

Se recomienda utilizar el Script Communicator para poder enviar la información de forma adecuada (recomiendo hacerlo en hexadecimal). Cualquier otro tipo de terminal no vale porque envía la información en ASCII (es decir, que los números no son números en sí, sino un código, lo mismo para las letras), 

Saludos.
Serial_I2C.ice
Modulos_I2C_only_write.zip

Democrito

unread,
Sep 6, 2019, 5:17:20 AM9/6/19
to FPGAwars: explorando el lado libre
Se me olvidó comentar que para la Icezum Alhambra hay que conectarlo a las patillas amarillas, las que no llevan el conversor de tensión, para que pueda hacer el tema del tri-estado. En Alhambra II, pese a que la tengo, todavía no lo he probado ahí, pero estoy seguro que se puede conectar en cualquier patilla.

charli va

unread,
Sep 6, 2019, 6:04:24 AM9/6/19
to fpga-wars-explora...@googlegroups.com
Mil gracias Demócrito! gracias por compartir y elaborar las explicaciones!

El vie., 6 sept. 2019 a las 11:17, Democrito (<spo...@gmail.com>) escribió:
Se me olvidó comentar que para la Icezum Alhambra hay que conectarlo a las patillas amarillas, las que no llevan el conversor de tensión, para que pueda hacer el tema del tri-estado. En Alhambra II, pese a que la tengo, todavía no lo he probado ahí, pero estoy seguro que se puede conectar en cualquier patilla.

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/91b14002-1066-4083-8106-dbfa92a88132%40googlegroups.com.

Obijuan

unread,
Sep 6, 2019, 1:58:39 PM9/6/19
to FPGAwars: explorando el lado libre

Woala Demócrito!!!!  El circuito tiene una pinta estupenda!!!!!! ¡Me encanta! :-)

Me voy a comprar un AD5280 para probarlo

Lo has resuelto super bien!  Mándanos vídeos con las pruebas porfa! :-)

Muchas gracias por compartirlo

Saludos, Obijuan



Democrito

unread,
Sep 6, 2019, 2:26:04 PM9/6/19
to FPGAwars: explorando el lado libre
Muchas gracias Carlos y Juan!

Juan, No te lo compres para probarlo!!! (es un verdadero rollazo porque hay que comprar tb la plaquita DIP que lo adapta, y es infernal soldar algo con la patas tan pequeñas y juntas.) Buscaré otra cosa más común y corriente! Tengo un luz medio encendida en mi cabeza, me vino al despertar de una siesta, de hacerlo mucho mejor y más eficiente (a nivel de cantidad de componentes). Y faltan detalles como comprobar los posibles errores y que tb pueda leer. Si no me he metido con el Z80 es porque quiero de alguna manera terminar con este proyecto, o al menos hasta donde pueda llegar.

Un abrazo fuerte a los dos! (Sois la leche!, en el mejor de los sentidos.)

Democrito

unread,
Sep 7, 2019, 7:36:12 PM9/7/19
to FPGAwars: explorando el lado libre
Hola de nuevo!

Antes de comenzar, un vídeo de demostración de escritura a través del I2C. (Perdón porque sale invertido pero se ve el funcionamiento, antiguamente había una opción con esto, pero parece que la han eliminado): https://youtu.be/KpxlNsCDO20

Yo ahí utilicé una LCD sin luz de fondo, pero si lo probáis os recomiendo que la tenga. Lo grabé así porque de otro modo la cámara no captaba el texto porque la luz lo impedía. Al final de la demostración dicha luz ha de parpadear 3 veces.

He adaptado el anterior diseño para el caso que toco en este post. Se trata de enviar información al chip PCF8574, que es un expansor de bus y funciona a través del I2C. Es muy común que lo tengamos porque lo solemos usar en pantallas LCD, nos resume muchos cables en sólo dos.

El esquema me ha quedado así:

i2c_LCD_fpga.PNG

Sólo se necesita un byte de dirección y otro de datos.

Cuando traté de hacer funcionar este proyecto (hasta hace unas pocas horas) desconocía cómo se enviaba información a una LCD, y desconocía el funcionamiento del PCF8574. Me tuve que informar bien, porque conectarlo a un Arduino es algo trivial, pero hacerlo a una FPGA estás obligado a comprender el funcionamiento de todas las parte y así saber qué has de hacer.

En modo muy resumido el PCF8574 es un circuito que recibe información del I2C y lo transforma en un bits de salida. No hace nada más que eso. Sus patas pueden ser configuradas como entradas o como salidas, dependiendo de si queremos leer o escribir.

Por ejemplo, si en Arduino ponemos:

Wire.write(255);

Le estamos diciendo que envíe ese 255 al I2C, y cuando lo lea el PCF8574 lo convierta en 8 bits de salida, que en este caso es poner todas sus patas a 1.




Es decir que P0, P1... P7 se pondrán a 1. Observa P3, es una salida con el colector abierto, por ello necesita una resistencia en configuración pull-up. La cosa es que este chip lo han adaptado a una PCB para que pueda ser directamente conectado a una LCD estándar.

Luego busqué información de cómo trabaja un LCD y dí con una web en la que flipé pepinillos. El tío no usa nada más que interruptores, sin micros ni electrónica añadida. Es tan básico el proyecto que se comprende perfectamente cómo funciona a la primera. En nuestro caso la información se envía de 4 en 4 bits (un nibble), luego dando un flanco de bajada en la patilla E (enable) del LCD toma dicha información.

Pues en el circuito con FPGA tuve presente todo eso, y gracias a una máquina de estados de contar todo se simplifica mucho. Dentro de la ROM puse la información en binario porque para mí era mucho más cómodo trabajar así, ya que tenía que saber qué bits se tenían que poner a 1 ó a 0.

La cuestión es que hice funcionar el potenciómetro digital (post anterior) y ahora el PCF8574, por tanto la filosofía de diseño funciona, eso sí, sólo vale para enviar información. Tengo en la cabeza un nuevo diseño que consumiría menos recursos que el diseño que estoy presentando.

Adjunto el ICE de demostración. Para hacerlo funcionar sólo hay que pulsar SW1, eso es todo. Para repetir el experimento es necesario desconectar la alimentación (o el USB) y volver a conectar.

Saludos!

Bibliografía:

Saludo.ice

Democrito

unread,
Sep 7, 2019, 7:58:51 PM9/7/19
to FPGAwars: explorando el lado libre
En mi caso la dirección es 0x27 y la pongo en decimal dentro de Icestudio (39). Igual os toca otra dirección, no tiene por qué coincidir. Existe un pequeño programa para Arduino que te permite conocer la dirección de cualquier esclavo que funcione por I2C: https://www.prometec.net/wp-content/uploads/2014/10/I2C_scan.rar

charli va

unread,
Sep 8, 2019, 2:38:42 AM9/8/19
to fpga-wars-explora...@googlegroups.com
Hola democrito!! Que gran trabajo!!!

Si te interesa el tema del lcd mira en mi repositorio

Que ando trabajando en una librería para icestudio para lcds (la compartí por twittee y ya no recuerdo si la puse aquí)

Le metí varios ejemplos chulos y sobre todo los primeros diseños están muy documentados.

Está aún en versión beta, la quiero retomar estos días con el z80 y aprovecharé a cerrar y corregir bugs.

Un abrazo!

El El dom, 8 sept 2019 a las 1:58, Democrito <spo...@gmail.com> escribió:
En mi caso la dirección es 0x27 y la pongo en decimal dentro de Icestudio (39). Igual os toca otra dirección, no tiene por qué coincidir. Existe un pequeño programa para Arduino que te permite conocer la dirección de cualquier esclavo que funcione por I2C: https://www.prometec.net/wp-content/uploads/2014/10/I2C_scan.rar

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

Democrito

unread,
Sep 8, 2019, 5:08:01 AM9/8/19
to FPGAwars: explorando el lado libre
Madre mía Carlos, eso sí que es meterse en las tripas de un LCD...! No conocía ese enlace, muchas gracias!

charli va

unread,
Sep 8, 2019, 6:29:40 AM9/8/19
to fpga-wars-explora...@googlegroups.com
Si te motiva y quieres avanzar cosas o incorporar el control del potenciometro dale caña y lo metemos en la librería!!

El El dom, 8 sept 2019 a las 11:08, Democrito <spo...@gmail.com> escribió:
Madre mía Carlos, eso sí que es meterse en las tripas de un LCD...! No conocía ese enlace, muchas gracias!

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

Jose Pico

unread,
Sep 8, 2019, 6:26:22 PM9/8/19
to FPGAwars: explorando el lado libre
Que Bueno!

 Muchas Gracias. 

Democrito

unread,
Sep 8, 2019, 8:13:24 PM9/8/19
to FPGAwars: explorando el lado libre
He conseguido hacer el mismo circuito pero sólo gastando los flip-flops inevitables y necesarios. En un post más arriba comenté que la forma de onda del SCL también lo hacía con flip-flops pre-programados, en este segundo circuito sólo utilizo lógica para crear dicha señal SCL.

La versión anterior consume estos recursos (versión mínima) : 

p2.PNG


Y la versión que acabo de hacer consume estos recursos (versión mínima):


prueba1.PNG


De  89    FFs   pasamos  a 38.

De 100   LUTs pasamos  a 76.

De  64    PLBs pasamos  a 33.


La diferencia en general es bastante notable.


Adjunto la última versión. Como es muy tarde lo he de dejar aquí por hoy. En los próximos días trataré de sacar varias versiones para que pueda cumplir la mayoría de las necesidades.


Saludos.


I2C_write.ice

Democrito

unread,
Sep 8, 2019, 8:48:27 PM9/8/19
to FPGAwars: explorando el lado libre
Había probado el funcionamiento sólo mirando las salidas del PCF8574. Pero al probarlo con la LCD... algo hace raro, no salen las letras, pese a que hace los 3 parpadeos finales.

Así que... Ya sabéis. La última versión peta.

Democrito

unread,
Sep 8, 2019, 9:30:30 PM9/8/19
to FPGAwars: explorando el lado libre
Perdón por la pesadez, pero no podía dormir!

Ya está arreglado, me estaba comiendo un ciclo de la señal SCL (dentro del módulo "Stop"). Me tengo que comprar el analizador de señales que siempre comentáis porque ir así es ir a ciegas y encima el osciloscopio que tenía se me escacharró hace tiempo (de esos malos tipo USB).

Vuelvo a adjuntar corregido el módulo principal y el ejemplo con el LCD, pero hasta que no le haga pruebas más exhaustivas no se puede lanzar las campanas al vuelo, luego siempre me pasa lo que me pasa.
I2C_write_corregido.ice
Saludo_Nueva_version.ice

Jose Pico

unread,
Sep 9, 2019, 2:25:00 AM9/9/19
to fpga-wars-explora...@googlegroups.com
El SAV te puede!
Muchas Gracias!
Seguro q esto es el principio de un gran I2c

--
Has recibido este mensaje porque estás suscrito a un tema del grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/fpga-wars-explorando-el-lado-libre/QZqGqehCvuk/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/c249ec84-f2f0-4537-995d-769ba98512cd%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages