Skip to content

OLED‐ssh1106

Juan Gonzalez-Gomez edited this page Feb 2, 2024 · 42 revisions

Introducción

Me he comprado esta pantalla OLED en BricoGeek

https://tienda.bricogeek.com/pantallas-oled/905-pantalla-oled-13-ssh1106-128x64.html

Es una OLED de 128x64, que tiene el chip SSH1106. La comunicación es por SPI de 4 hilos

La hoja de datos del chip que lo controla es esta:

https://cdn.velleman.eu/downloads/29/infosheets/sh1106_datasheet.pdf

Hay muchas conexiones. La que creo que lleva el de bricogeek es un SPI de 4 cables: SCL (reloj), CS, MOSI y A0 (DC) que se usa para indicar si lo que se envía es un dato o un comando (Igual que el LCD 2x16)

En la página 41 se pueden ver los tiempos asociados al SPI. La frecuencia máxima del reloj es de 2Mhz (500ns de periodo)

Así que tengo que hacer un SPI de 2Mhz. El que tengo hecho de la flash es de 12Mhz (la velocidad del sistema)

Aquí hay información sobre la conexión a un arduino:

https://www.14core.com/wiring-the-128x64-1-3-inch-oled-display-on-4-wire-3-wire-i2c-interface/

Demócrito tiene informacion buenísima aquí:

https://github.com/Democrito/repositorios/tree/master/OLED/Lines

He probado el ejemplo de dibujar la línea.. ha funcionado a la primera y muy bien!!!

Esto está pidiendo a gritos hacer un pcb protipo para que las conexiones sean más sencillas...

La idea es hacer un controlador básico desde 0, documentando todo y aprendiendo todos los detalles internos. Como hay muchos tipos de pantalla OLED, me voy a centrar exclusivamente en esta de BricoGeek, que va por el SPI de 4 hilos con el chip SSH1106

LOG

2024-01-27

Esta es la pantalla OLED conectada en una breadboard mini:

Las señales son:

Pin Descripcion
GND Masa
VCC Alimentación
CLK Reloj del SPI
MOS Datos de entrada (FPGA->OLED)
RES Reset de la OLED
DC Data (1) / Command (0). Indica si el byte enviado por el spi es un dato para dibujar en la pantalla o un comando
CS Es el SS del SPI

Este protocolo se denomina SPI a 4 hilos. Es un SPI normal (SCK, MOSI, SS) al que se le añade la señal DC para indicar el tipo de comando

Podemos encontrar más información en el Datasheet del chip SSH1106:

https://cdn.velleman.eu/downloads/29/infosheets/sh1106_datasheet.pdf

En la página 4 hay más información sobre los pines. La señal RES es activa a nivel bajo. Normalmente debe estar a 1. Cuando se pone a 0 el display se reinicializa a sus valores por defecto

Experimento 1: Puesta en marcha

Partimos de los ejemplos básicos de Demócrito, para poner uno en marcha y comprobar que el conexionado y todo está ok

Este será el ejemplo 1, que hay que poner en marcha:

https://github.com/Democrito/repositorios/tree/master/OLED/Lines/Simple_examples

La señal RES la cableamos a 1 (vcc) directamente, por lo que en el ejemplo sólo se usan los 4 cables de este SPI special (CLK, MOSI, DC, CS)

ESte es el montaje:

Y quí se ven más detalles de las conexiones con los pines:

Este es el circuito de prueba de Demócrito:

Lo cargamos en la Alhambra y lo probamos. Nada más conectarlo aparece "Ruido" en la pantalla. Esto es lo esperado, como indica Demócrito

Al apretar el pulsador SW2 se transfiere la imagen a la pantalla OLED, y aparecen 4 puntos en las 4 esquinas de la OLED, tal cual indica demócrito en su documentación

Ahora pulsador SW1 para que se dibuje la línea en la memoria externa, y nuevamente SW2 para transferir esa memoria al OLED. Este es el resultado: la línea se ha dibujado!

Este ejemplo de Demócrito ha funciona perfectamente, y será mi base de estudio para construir un controlador de la OLED desde 0, usando la conexión SPI

Experimento 2: Cambiando el cableado

Ahora que está funcionando, voy a cambiar el cableado para que sea más fácil el montaje. Voy a hacer que se pueda conectar con un fajo de 7 conectores macho-hembra. La conexión la voy a hacer a partir del pin D8 (D8-D12), para dejar libreos los pnes D0-D7 para poder conectar en ellos la AP-LED8 o cualquier otro periférico PMOD

6 5 4 3 2 1 0
Señales OLED GND VCC CLK MOS RES DC CS
Pines Alhambra GND VCC D12 D11 D10 D9 D8

El pin D13 todavía queda libre para conectar otro periférico (un led?)

El nuevo circuito de Icestudio es este:

Se han cambiado los pines a los nuevos. Se ha añaido el pin RES que siempre se pone a 1 y se han añadido etiquetas para que el diseño sea más legible. También se han eliminado los pines NC que había

Este nuevo circuito funciona perfectamente. Este es el recableado y el resultado de las pruebas:

Cambiamos el cableado a los nuevos cables (comprados en BricoGeek también):

También he conectado la AP-LED8 para mostrar que queda espacio libre

PCB Prototipo

Para que el conexionado sea más rápido, y no tener que estar con la protoboard, conectando y desconectando cables, he creado este PCB prototipo para conectar la pantalla OLED:

Y así es como queda al conectarlo a la Alhambra-II, junto con la placa AP-LED8-THT:

Está probado y funciona bien!! Ha funcionado perfectamente el ejemplo de Demócrito

Domingo, 2024-01-28

Experimento 3: Probando el reset

Vamos a probar la pata del reset, a ver qué pasa. El reset es activo a nivel bajo: cuando RES es 0, se hace el reset y todos los registros internos se inicializan. La situación normal es `RES' igual a 1

Usamos este circuito simplificado. Se ha aliminado la parte de dibujar la línea. Con el pulsador SW1 se dibujan los 4 puntos en las esquinas, y al apretar SW2 se hace el reset de la pantalla

Este es el estado cuando arrancamos la placa y pulsamos SW1:

Al apretar el botón de RESET la pantalla se apaga. Para que vuelva a arrancar hay que hacer un reset de la FPGA, pulsar SW1 y la pantalla se vuelve a encender mostrando los 4 puntos

Experimento 4: Comando para encender la OLED

En la hoja de datos, a partir de la página 19 se describen los comandos de la pantalla OLED. En la página 23 se describe el comando DISPLAY ON/OFF

Se indica que por defecto, al arrancar, la pantalla está APAGADA. Para encenderla hay que enviar el comando 0xAF. Este es el objetivo de esta prueba: un circuito que envíe por el SPI el comando 0xAF para encender la pantalla

Hay que enviar dos cosas, por un lado el dato/comando de 8 bits (0xAF en este caso). Por otro lado el bit DC que indica si es un dato o un comando. En nuestro caso un 0 porque es un comando. Al apretarse el pulsador SW1 se captura el dato y se envía. En paralelo se captura el valor de dc. Según el cronograma, este valor lo captura la OLED tras la recepción del dato. Por eso hay que capturarlo al comienzo

El resultado de las pruebas es que efectivamente al apretar SW1 se enciende el LED. Y al darle a SW2 se hace reset (y se apaga la pantalla)

¡¡Funciona!!!. Ya tenemos un controlador básico de bajo nivel, que envía un comando/dato a la pantalla OLED Cuando se enciende la pantalla, por defecto lo que muestra es "ruido". La memoria contiene cualquier cosas, y se muestra:

Experimento 5: Encender/apagar la pantalla

En este experimento enviamos el comando 0xAF para encender el Display al apretar el pulsador SW1. Al apretar el pulsador SW2 se envía el comando 0xAE para apagarlo

Funciona bien. Aunque he detectado que a veces el OLED no se inicializa bien. Tal vez convenga tener un pulsador externo para hacer reset del OLED

Experimento 6: Encender/apagar pantalla. Refactorización

Para ir poco a poco ampliando el circuito, voy a encapsular el controlador actual en un nuevo bloque. El envío de los comandos de ON y OFF lo voy a hacer a través de un bus

Además he añadido el botón externo de reset, para llevar la OLED al estado original

Este es el circuito:

Funciona perfectamente

Experimento 7: Lamp test: Encendido de todos los píxeles

El comando set entire display (0xA5) activa todos los píxeles del display (no afecta al contenido de la RAM). El comando 0xA4 vuelve al modo normal (para mostrar lo que hay en la RAM)

En este circuito el pulsador SW1 enciende la pantalla, y el pulsador SW2 enciende todos los LEDs:

Este es el resultado del lamp test:

¡Funciona! Comando controlado

Experimento 8: Lamp test ON/OFF

En este experimento se usa el pulsador SW1 para encender la pantalla. A continuación se entra en un bucle en el que cambia de estado con cada pulsación de SW1: Primero se activa el modo lamp-test y a continuación se desactiva

El comando para desactivar el lamp-test es 0xA4

Lunes, 2024-01-29

Experimento 9: Escritura de datos

Para escribir datos en la memoria de video de la OLED, y que se muestre algo en pantalla hay que poner la señal dc a 1. En este experimento hacemos un circuito que enciende la pantalla al pulsar SW1 (envío del comando 0xAF). En las sucesivas pulsaciones de SW1 lo que se envía a la OLED es el dato 0xFF, para ver qué ocurre...

En la tercera pulsación de SW1 (tras el encendido de la pantalla) aparece una línea vertical de 8 píxeles encendiddos en la esquina inferior derecha. Si continuamos apretando SW1 aparecen más líneas, que se desplazan de izquierda a derecha, en la parte inferior. En esta imagen vemos lo que ha ocurrido cuando tenemos 16 líneas:

Las conclusiones de este experimento son las siguientes:

  • El origen está en la esquina inferior derecha
  • Con cada escritura de un valor se auto-incrementa la posición actual, que pasa a la siguiente hacia la izquierda
  • Las dos pulsaciones primeras escribien en dos posiciones NO VISIBLES. La tercera ya sí se corresponde con el origen
  • Si escribimos más de 128 valores, vemos que sólo se rellena la línea inferior de 8 píxeles de alto. NO al resto de la memoria

Hay que leer la hoja de datos para obtener más información

Experimento 10: Flip vertical (y)

Leyendo el datasheet de la OLED vemos que existen un comando: 0xC8 que cambia el renderizado de la OLED de forma que se hace un flip del eje y. Con el comando 0xC0 se vuelve al modo original

Lo probamos con este circuito que inicialmente activa la OLED y luego envía consecutivamente los comandos 0xC8 y 0xC0 alternativamente con cada pulsación de SW1

En las imágenes es difícil ver el flip, pero en directo se ve perfectamente cómo cambia:


Conclusiones del experimento:

  • Como parte del proceso de inicialización hay que activar la pantalla y hacer un flip-y
  • Necesitamos encontrar cómo hacer un flix para que el origen se sitúe en la esquina superior izquierda

Experimento 11: Inicialización y escritura de valores

El comando para hacer flip-x es el 0xA1, y para volver al estado inicial el 0xA0. Sin embargo este comando no afecta al render de la OLED actual por lo que al aplicarlo no vemos ningún cambio en la pantalla. Lo que ha hecho flip-x es el cursor: la posición actual donde se van a escribir nuevos datos

En este experimento hay que apretar 3 veces el pulsador SW1 para realizar la inicialización del LED. Tras ello, el origen ya está en la esquina superior izquierda. A continuación se entra en la fase de escritura de datos. Hay que apretar otras 3 veces más para obtener la primera barra vertical (0xFF)

Este es el resultado. Se ha apretado SW1 muchas veces para realizar la escribura de 16 barras verticales de 8 píxeles. Se ve que aparecen ahora en la posición correcta: Esquina superior izquierda

Experimento 12: Selección de página

La memoria de video está dividida en 8 bancos de 8 líneas cada uno. Eso nos da las 64 líneas de altura. Por defecto está seleccionado el Banco 0, que incluye las primeras 8 líneas. Mediante el comando 0xBN, donde N = 0...7 es el número de banco. En este ejemplo se selecciona el banco 1 (0xB1). Las escrituras de datos se hacen, por tanto, en ese banco:

Este es el resultado. Ahora vemos que los valores introducidos aparecen 8 líneas por debajo del ejemplo anterior:

Cambiando en el circuito de pruebas el valor del banco: Comandos 0xB0, 0xB1...0xB7 ... vemos cómo efectivamente se cambian las líneas donde escribir los datos

Experimento 13: Selección de columna

El comando Set-LCOL (0x0N) permite establecer el valor de los 4 bites de menor peso del registro de columnas (N es la posicion). El comando Set-HCOL (0x1N) establece los 4 bits de mayor peso

En este experimento estableemos el valor de la columna a 0x0F, de manera que se escribe a partir de la posición 15

Vemos el resultado:

Efectivamente se empieza a escribir en una posición situada más a la derecha... PERO no es exactamente la posición 15 en la pantalla. En la pantalla empieza en el pixe 13 (empezando desde el 0). Es debido a que las posiciones 0 y 1, por una razón que todavía desconozco, NO APARECEN en la pantalla. La zona visible empieza a partir de la posición 2 (contando desde 0). Es decir, hay 2 píxeles en la zona de la izquierda que no son visibles

Esto en principio podría tener algo que ver con la inicialización. Hay que configurar algo... pero vete tú a saber qué... Esto lo estudiaré más adelante

Experimento 14: Inicialización Manual

En este experimeto, al apretar SW1 se realiza la inicialización completa:

  • Encender oled
  • Flip-y
  • Flip-x
  • Establecer la x=2 como inicio (ya que es lo que se ve en la pantalla...)

Una vez terminada la iniciación, el LED0 se enciende. A partir de ahí, si pulsamos SW1 se imprimirá en la pantalla el valor 0xFF (líneas verticales de 8 bits)

Este es el circuito:

Lo probamos y funciona según lo esperado. Primera pulsación: inicialización. Segunda pulsación aparece una | en la primer posición (que en realidad es la 2 por motivos desconocidos...)

Experimento 15: Pruebas de configuración

He reducido la configuración inicial el ejemplo de Demócrito a lo mínimo: inversion eje x, inversion eje y, y activar la pantalla.... El ejemplo sigue funcionando con normalidad... Entiendo que el circuito de Demócrito tiene en cuenta que lo que se dibuja en la pantalla es desde la dirección 02 (columna 2)...

La conclusión que saco es que no hay ningún comando de configuración especial...

SOLUCIONADO!!!

Efectivamente en el Circuito de demócrito, cada vez que se accede a una página nueva hay que enviar 3 bytes:

  • Bx: donde x es la página (0-7)
  • 02: Establecer el nibble bajo de la columna a 2
  • 10: Establecer el nibble alto de la columna a 0

Experimento 16: Inicialización automática

En este experimento vamos a hacer que la pantalla se inicialice automáticamente, sin esperar a pulsar SW1... Para ello hay que leer los tiempos en la hoja de datos

En la página 44 aparece el timming del reset. Debe permanecer al menos 10µs a nivel bajo. Luego estar 1µs hasta que se completa el reset. En la página 32 se indica el proceso completo de inicialización del display. Tras el comando 0xAF hay que esperar al menos 100ms antes de poder enviar datos al display... El CLS se hace antes de encender el display

Para generar un retraso de 10µs hay que esperar 120 ciclos de reloj

ciclos = 10µs * 12Mhz = 120

Necesitamos un contador de 7 bits: nos genera un retraso de 128 ciclos

Por los experimentos hecho, además hay que esperar un cierto tiempo (estoy usando 100ms) antes de hacer el reset. Es necesario para que funcione cuando se enchufa al USB, y por tanto el LCD tiene que arrancar... antes de hacerle el reset damos un poco de tiempo

Este es el circuito que empíricamente ha funcionado bien:

Ahora, al conectar la placa, se envía el reset, se inicializa el display, y queda a la espera de pulsar SW1. Con cada pulsación se escribe el valor 0xFF que provoca la aparición de 8 píxeles verticales en el origen, con auto-incremento. Al darle más veces al SW1 se escribe la barra en las posiciones siguientes...

Funciona muy bien!!! Todo listo para implementar rutinas de CLS!

Martes, 2024-01-30

Experimento 17: Encapsulación!

Toda la inicialización y preparación del display lo metemos en un bloque. Una vez acabado este proceso, se invoca al proceso de usuario, que escribe una serie de valores en el primer banco...

Este es el nuevo circuito:

¡Queda super simplificado!

Experimento 18: Escribir dos valores con SW1 y SW2

En este experimeto se imprimen dos valores diferentes: 0x55 y 0xAA con las teclas SW1 y SW2 respectivamente

Ahora podemos crear patrones en la página 0:

Experimento 19: Escribir dos valores con SW1 y SW2 en otra página

Ahora hay que hacer lo mismo, pero primero cambiamos de página. Esto nos permitirá probar que el envío de comandos funciona desde este nivel superior

Para facilitar las cosas vamos a hacerlo a través de un bus de 9-bits. Los 8 de mayor peso llevan el dato, y el de menor peso indica si se trata de un dato o un comando.

Cuando se termina la inicialización del OLED (init_done) se envía el comando 0xB1 para situarse en la página 1. Al apretar SW1 ó SW2 se envían los dos valores de prueba. El comando 0xB1 lo construimos a partir de sus nibbles. Uno es fijo: 0xB y el otro indica la página, que en este ejemplo es la 1. Se puede poner cualquier valor entre 0-7

Este es el resultado:

Experimento 20: Escribir varios valores en una página

El circuito se va complicando. Lo primero que hacemos es pasar a un bus de 10 bits. Ahora lleva los 9 bits del comando/data más el bit de transmisión para arrancar el SPI

El sistema lo controla un autómata que primero envía la página, luego envía la columna y por último activa una máquina de contar de 128 (7 bits) para enviar el patron 0x81 a todas las posiciones de la página seleccionada

En el LCD vemos este patrón en la página 1:

Experimento 21: Relleno de varias páginas

Este circuito es más complicado. Habrá que modularizarlo poco a poco para que se pueda entender mejor y expandir

La idea es que hay un autómata que activa una máquina de contar de 0 a 7, que cuenta páginas. Por cada página el autómata envía el comando page seguido de coll y colh para situar el cursor al comienzo y luego imprime 128 caracteres

Según el valor1 establecido, saldrán diferentes patrones, como borrar la pantalla, líneas horizontales, pantalla rellena...

Esto es lo que aparece en la pantalla:

Experimento 22: Dibujo de Patrones

Partimos del circuito anterior. Ahora cambiamos el valor a imprimir en la pantalla (valor1). En vez de ser un valor constante para todas las posiciones de la pantalla, varía según la columna y la página. Se consiguen patrones muy interesantes. Uno muy chulo es si simplemente imprimimos en cada página el valor de la columna.. sale un patrón que recuerda a un fractal...

En este circuito se utilizan multiplexores como instrucciones IF para dibujar un marcho. Si la página es la 0, se dibuja un pixel superior (para que se cree una línea horizontal de 128 píxeles). Si la página es la último, el valor es un pixel inferior (línea horizontal). Si la columna es 0, se dibua una barra vertical y si la columna es 127 se dibuja otra barra vertical. En el resto de casos se imprime 0 para borrar esa posición. El resultado es que sale un marco... ¡Mola!

Este es el resultado del marco:

miércoles, 2024-01-31

Antes de seguir avanzando tengo que refactorizar los bloques, para que el circuito quede más simplificado. La idea es usar bloques como andamios: para que me permitan avanzar en las pruebas. No son bloques definitivos ni están "bien pensdos". Simplemente son funcionales y permiten liberar espacio y complejidad para explorar los siguientes niveles

Experimento 23: Bloque para escritura de datos

Ya tengo hecho un bloque para escribir directamente en el bus de la OLED un dato. Este componente, además, mantiene el estado. Cuando se activa su entrada de write, cambia a busy y envía el dato al SPI. Se queda esperando a que el SPI complete la transacción, y cuando esto ocurre lo notifica por su salida done

Esto permite que se puedan en cadenar estos bloques y no tener que añadir un autómata de control

En el ejemplo se imprime 2 valores consecutivos al apretar el pulsador SW1, y otro valor diferente al apretar SW2

Como son bloques "andamio", no voy a crear imagen SVG... lo dejo para más adelante

Experimento 24: Bloque de escritura de página

Ya está encapsulado en un bloque el circuito para rellenar una página entera. Una de las salidas es la columna actual (col). Sirve para que el valor a introducir de relleno sea función de la x, y crear así patrones interesantes. En este circuito se introduce un valor fijo

El bloque funciona perfecto!

Experimento 25: Bloque para introducir la columna

Este es el bloque para escribir el nibble bajo de la columna (col_l), y también el alto (col_h)

Experimento 26: Bloque para establecer la página

Ya tenemos el bloque para establecer la página (0-7). Funciona perfectamente!

Experimento 27: Bloque para repetir las páginas

Bloque para repetir las páginas listo!!! Ya lo tengo todo listo para refactorizar!

Experimeto 28: Bloque para rellenar la pantalla de un valor (CLS)

Con este circuito ya se puede hacer el CLS, o rellenar la pantalla con cualquier otro valor

Experimento 29: CLS y escritura

Ya con el bloque CLS encapsulado... este circuito borra la pantalla nada más empezar, y escribe el valor 0xFF en la esquina superior izquierda. Al apretar el pulsador externo se imprime otro valor 0xFF

Así queda la pantalla al arrancar:

Jueves, 2024-02-01

Experimento 30: sprites!

Es el momento de hacer un sprite... Voy a utilizar la llave del Manic miner, de 8x8, que hice en el log de aprendizaje del spectrum: https://github.com/Obijuan/Learn-zx-spectrum-asm/wiki/LOG#2023-07-15

Este es el sprite y sus valores. Los valores se toman por columnas, siendo el pixel de la parte superior el de menor peso y el inferior el de mayor

Estos valores los metemos en una tabla de 8x8 (8 posiciones de 8 bits) que se recorre con una máquina de contar que se activa al inicio (y también al apretar el botón). Al arrancar se hace un locate a la posición 0 y se escribe el sprite. Sucesivas pulsaciones hacen que aparezcan más llaves

Este es el circuito:

Y este es el resultado, cuando se aprieta el botón varias veces:

En esta imagen se muestra más detalle:

Y en esta más todavía:

Aquí dejo algunos sprites más para probar más adelante. Los dejo hechos en modo prototipo:

####   ##
####   ##
####   ##
####   ##
 ##   ####
 ##   ####
 ##   ####
 ##   ####

0F FF FF 0F
F0 FF FF F0

  ##    ##
 ####  #  #
 ####  #  #
  ##    ##

06 0F 0F 06 06 09 09 06

  ###    ###
 #####  #   #
 #####  #   #
 #####  #   #
  ###    ###

0E 1F 1F 1F 0E
0E 11 11 11 0E

   ##       ##
  ####     #  #
 ######   #    #
 ######   #    #
  ####     #  #
   ##       ##

0C 1E 3F 3F 1E 0C 00 00 0C 12 21 21 12 0C 00 00

   ###      ###
  #####    #   #
 #######  #     #
 #######  #     #
 #######  #     #
  #####    #   #
   ###      ###

1C 3E 7F 7F 7F 3E 1C 00 1C 22 41 41 41 22 1c 00

   ####      ####
  ######    #    #
 ########  #      #
 ########  #      #
 ########  #      #
 ########  #      #
  ######    #    #
   ####      ####

3C 7E FF FF FF FF 7E 3C
3C 42 81 81 81 81 42 3C

Experimento 31: Animación!

Voy a hacer la misma animación que hice para el zx spectrum: https://github.com/Obijuan/Learn-zx-spectrum-asm/wiki/Curso:-Dominando-Ensamblador-Z80,-para-ZX-Spectrum#reto-24-animar-un-sprite-de-8x8

Creamos los sprites y los metemos en el circuito. La organización es la siguiente: La tabla es ahora de 32 posiciones (5 bits de direcciones). Los 3 bits de menor peso indican la columna del sprite (0-7) a dibujar. Y los 2 bits de mayor peso indican el sprite a pinta (0-3)

Los sprites se pueden pintar en espacio o en tiempo. Esto lo cambiamos situando la etiqueta boton1 conectada al pulsador SW1 (espacial) o al corazón (tiempo).

El circuito completo es este:

Si lo confiramos en modo espacio y apretamos el pulsador SW2 4 veces, veremos la "animación" en el espacio: Se imprimen los 4 fotogramas de la animación, uno a continuación del otro. El último es otra vez el primero: (Se han dibujado 5 en total)

y aquí se muestra con un poco más de detalle:

Aquí se puede ver la animación en el tiempo, conectando la etiqueta boton1 al corazón:

Y esta es la animación con más detalle:

Jueves, 2024-02-02

Experimento 32: Volcado de la flash

Primero vamos a grabar contenido en la flash. Lo hacemos desde el Visual code. Metemos 16 sprites de 8x8:

Lo grabamos en la flash, en la dirección 0x04_0000

apio raw "iceprog -o 0x040000 sprites-1.bin"

Esta es la salida

obijuan@Hoth:~/Develop/Cuadernos-tecnicos-FPGAs-libres/wiki/OLED-ssh1106/Flash
$ apio raw "iceprog -o 0x040000 sprites-1.bin"
init..
cdone: high
reset..
cdone: low
flash ID: 0xEF 0x40 0x16 0x00
file size: 1035
erase 64kB sector at 0x040000..
programming..
done.                 
reading..
VERIFY OK             
cdone: high
Bye.

Este es el circuito que imprime en la pantalla, byte a byte, cada uno de los sprites:

Al apretar 16 veces el pulsador SW1 esto es lo que aparece en la pantalla:

Experimento 33: Animación desde la flash

Vamos a mostrar una animación de 8 fotogramas, leidos desde la flash. Lo primero que hacemos es crear los sprites de la animación. Voy a partir de un círculo de 4x4 píxeles y tomar 3 píxeles de su contorno. Este contorno avanza un pixel hacia la derecha. Este es el dibujo en Inkscape:

Para hacer pruebas hay más animaciones creadas. Cada animación empieza en una dirección diferente. Desde el circuito podemos cambiar la dirección inicial y final, para seleccionar una u otra:

Este es el resultado en la pantalla:

Experimento 34: LEDs virtuales

He creado un bloque para integrar un LED virtual. Lee el estado de un pulsador y lo dibuja en la pantalla, en la posición x indicada (en la página 0). He colocado dos en serie para ver dos LEDs virtuales. El circuito es este:

Este es el funcionamiento. Al apretar los pulsadores SW1 y SW2 su estado se refleja en los LEDs virtuales (Vídeo de youtube):

Click to see the youtube video

Clone this wiki locally