2022/07/19

Recuperación fallida pantalla bangho, premio consuelo webcam

Me habían regalado una bangho b-n0x1, que tenía de interesante dos slots MiniPCIE, (creo), uno ocupado por WiFi, el otro libre. La prendí, tenía un windows roto, la olvidé. Meses despues la quise prender y nada, murió algo y pasé a modo carroñero.

Disco ok, memoria veremos, teclado se me soltó la tecla de enter, lo más interesante la pantalla, a su lado una webcam...

 

Recuperación fallida


Gracias a un cierto esfuerzo y la generosa colaboración de Pablo Llanos en este hilo de embebidos, pasé de no saber absolutamente nada a saber porqué no puedo usar la pantalla, resumo:

La pantalla es una HannStar HSD100IFW1-A00, que se comunica con LVDS. Por medio de tres pares de cables se transmite:


g[0], r[5], r[4], r[3], r[2], r[1], r[0]
b[1], b[0], g[5], g[4], g[3], g[2], g[1]
de,   vs  , hs  , b[5], b[4], b[3], b[2
]


 
siendo supongo de Display Enable, vs Vertical Sync y hs Horizontal Sync. No importa mucho el detalle pero cuento mi idea, que era, a la usanza de los primeros video juegos, tener algo así como un Video Sync Generator y mediante lógica combinacional generar algo. Pero la frecuencia es de 45MHz, multiplicada por esos 7 bits de más arriba, 315 MHz, completamente fuera de mi alcance generar, tratar adecuadamente, medir o diagnosticar.
 
Luego pensé que si la disposición hubiese sido:
 

de,  g[0], r[5], r[4], r[3], r[2], r[1]
vs,  b[1], b[0], g[5], g[4], g[3], g[2]
hs,  b[5], b[4], b[3], b[2], r[0], g[1]


con las señales de control separadas, podrían haber posibilidades de trabajar a 90MHz, pero eso es en un universo alternativo.

En realidad no es que no sabía nada, estuve adaptando unos ejemplos de verilog que generan VGA, me he hecho un PMOD VGA e implementé un render de VGA en TCL para la salida de una simulación de FPGA, pero de esto nuevo no tenía ni la menor idea.

 

Premio consuelo


Me quedó la cámara web, con un chip que dice ser Aveo AV301W, una datasheet aparentemente compatible que dice "Delock industry USB 2.0 CMOS Kameramodul 1.3", no recuerdo el camino de navegación que me llevó hasta ahí, pero creo recordar que fue por la imagen.

 

Aveo AV301W
Aveo AV301W

 

Este módulo implementa comunicación USB, asi que tomé un cable USB roto, aposté a que la falla estaba cerca del conector del lado del dispositivo, corté, agregue un PCB para poder disociar la soldadura de la correcta conexión, miré los pinouts fijo, soldé y listo.

 

Del lado del cable, elegí "imágenes" en https://www.google.com/search?q=usb+pinout. Dejo como referencia con ASCII Art, viéndolo desde arriba:

 - D+ D-  +

[] [] [] []

 4  3  2  1


En el módulo:


Pin#Signal Name
1+5v
2USB_D-
3USB_D+
4BTN
5GND


BTN es un botón opcional para disparar capturas, no me molesté en conectarlo

Lo enchufé en una vieja Sarmiento y nada.

Superado por tanta derrota, abandoné el proyecto.

Semanas despues, reviví el proyecto.

El motivo de este resucitamiento fue una confluencia de astros: por un lado alguien ofreció hardware en embebidos32, lo que me llevó a cybercirujas, que me puso nuevamente en sintonía con el modo recuperador. Por el otro, con motivo a un proyecto candidato a H4CK3D 2022, estaba viendo una excelente clase de USB a cargo de Pablo Gómez y ví en un diagrama que D+ va con D+ y D- con D-, no como en UART que Rx va con Tx y Tx con Rx y me pregunté si lo había conectado bien. Al revisar, estaba bien conectado, pero no había soldado correctamente el pin de alimentación. 

Corregí, volví a conectar la cámara a la vieja Sarmiento y listo, anda.

Para llevar la sinergía al máximo, hallé tirado en la calle hace meses, sino años, un gabinete de webcam, en perfecto estado.

 

A medio armar


Que de premio extra traía un micrófono:

 

Micrófono
Micrófono


Le hice unas ranuritas, pístola de plástico caliente y listo.

El único problema es que el cable es un poco corto y en la máquina donde más serviría conectarla, con un alargador no anda, en otra si.


2022-10-23, por si algún día retomo https://hackaday.io/project/179868-all-about-laptop-display-reuse/log/193081-common-lvds-laptop-panel-pinouts




2022/05/04

Parte de Flisol 2022

En esta oportunidad expuse un mezcladito de varios open:

Open HW/Core/SW: SoC ICICLE con CPU RISC-V en EDU-CIAA-FPGA

A mi propuesta original que incluía el ataque mostrado en H4CK3D 2021, el Profesor Matías me recomendó podarla para que sea menos técnica. Esa poda fué insuficiente, ya el título es bastante largo y complicado, a la mayor parte de la asistencia no era un tema que le interesara, no importa, para FLISoL 2023 tengo pensado algo más apropiado.

 

Mi idea fue ir evolucionando distintas implementaciones de la luz ondulante de K.I.T.T. hasta llegar a un softcore en FPGA, aprovechando el trabajo de un montón de gente:

 

Historia
Historia

 Lo rojito a la derecha era mi objetivo, lo expuesto en H4CK3D 2021

 

La primera versión es con componentes digitales, la hice hace casi 35 años, un registro de desplazamiento con unas puertas OR animadas a continuación, con un 555 para el clock, unos OR, un flip flop y algún capacitor para  inyectar el primer bit.

Ese bit entra en la primera posición del registro de desplazamiento y en cada tick del clock se va moviendo, con la salida conectada a la entrada con un OR al flip flop que salvo en el arranque siempre está en cero, lo tenemos para siempre. Yendo hacia los leds, con los OR de la derecha transformamos el movimiento en un aparente ida y vuelta.

K.I.T.T. con compuertas digitales
K.I.T.T. con compuertas digitales

 

Comparando precios, el costo es similar a implementarlo con un microcontrolador. Ponemos un bit en uno y lo vamos desplazando para un lado hasta detectar que llegó al punto deseado, ahí invertimos el sentido del movimiento, para siempre.


K.I.T.T. con microcontrolador y lógica específica
K.I.T.T. con microcontrolador y lógica específica

El programa es corto pero complicado e inadaptable a otros patrones. Una versión mejor aunque te indigne desde el punto de vista de la programación es:

while (true) {
  gpio_A.out(1);
  delay(DELAY);
  gpio_A.out(2);
  delay(DELAY);
  gpio_A.out(4);
  delay(DELAY);
  gpio_A.out(8);
  delay(DELAY);
  gpio_A.out(16);
  delay(DELAY);
  gpio_A.out(8);
  delay(DELAY);
  gpio_A.out(4);
  delay(DELAY);
  gpio_A.out(2);
  delay(DELAY);
  gpio_A.out(1);
  delay(DELAY);
}

¿Por qué me atrevo a incluir esta manera? Pues por que es el precursor para esta version más linda, en lugar de código hardcodeado, la información está en un array:

unsigned int out[]={1,2,4,8,16,8,4,2,1};
int pos = 0;
int limit = sizeof(out)/sizeof(out[0]);

while ( true) {
  gpio_A.out(1);
  delay(DELAY);
  ++pos;
  if (pos == limit) {
    pos = 0;
  }
}

y esto se parece mucho a la implementación nuevamente con componentes digitales.

K.I.T.T. con contador y memoria
K.I.T.T. con contador y memoria
 

Ahora, tanto en hardware como en software, podemos con gran facilidad mostrar otros patrones manipulando la memoria o el array según corresponda:

 

K.I.T.T. con contador y memoria y patrones arbitrarios
K.I.T.T. con contador y memoria y patrones arbitrarios

 

En la charla acompañando a esta evolución también fui contando como funciona una computadora a un nivel más bajo, que me cuesta mucho convertir a este formato, quizás haga un video en algún momento, lamentablemente no pude grabar la sesión.


Eso llevó a la explicación de FPGA y RISC-V, desembocando en el tema que me interesaba, la implementación primero en Verilog de la versión con lógica, como dispositivo incluido en el SoC icicle:

https://github.com/cpantel/evilCodeSequence/blob/master/kitt.sv

module kitt #( parameter BASETIME) (
    input clk,
    input reset,
    output [4:0]display_out,
    /* memory bus */
    input [31:0] address_in,
    input sel_in,
    //input read_in,
    //output logic [31:0] read_value_out,
    input [3:0] write_mask_in,
    input [31:0] write_value_in,
    output logic ready_out
);

    logic [25:0]q;
    logic direction;
    logic [4:0]display;

    assign ready_out = sel_in;
    assign display_out = display;

    always_ff @(posedge clk) begin
        if (reset) begin
            display <= 1;
            direction <= 1;
        end else if ( q > ( BASETIME / 1000 * 300 ) ) begin
            q <= 0;
            if (direction ) begin
                 if ( display[4] ) begin
                     direction = ~ direction;
                     display <= display >> 1;
                 end else
                     display <= display << 1;
            end else begin
                 if ( display[0] ) begin
                     direction = ~ direction;
                     display <= display << 1;
                 end else
                     display <= display >> 1;
            end 
       end else begin
            q <= q + 1;
            display <= display;
       end
    end

endmodule

 

Y por software, de modo concurrente y absolutamente independiente, ejecutándose en la CPU:

 

/*
  This program implements a SW kitt
*/

#include <stdint.h>
#include "../memmap.h"
#include "../uart.h"
#include "../delay.h"


int main() {
    uart_init();

    uart_puts("KITT starting\r\n");
    for (;;) {
        LEDS = 1;
        delay();
        LEDS = 2;
        delay();
        LEDS = 4;
        delay();
        LEDS = 8;
        delay();
        LEDS = 4;
        delay();
        LEDS = 2;
        delay();
        uart_puts("KITT .\r\n");
    }
}

 

 

Si algo entendés de Verilog, te darás cuenta que ese dispositivo como que está en vano conectado a los buses, ya que no hay nada con lo que el programa en la CPU pueda interactuar. Es que me quedé sin tiempo, querría al menos haberle permitido cambiar la velocidad.

En una próxima entrega espero no muy lejana, mostraré la implementación de un nuevo dispositivo que he de llamar "sequencer", que consistirá en una lógica que lea un trozo de memoria y lo exponga en los leds (vía PMOD como es ahora kitt) y que desde el programa se pueda arrancar, detener, pausar, cambiar la velocidad y modificar esa memoria.