Estoy manejando una interfaz ILI9230 LCD 320*240 de 16 bits, con un framebuffer de 250*200 y quiero manejarlo como 4 bits. así que construí una tabla de colores de búsqueda como esa:
u16 LUT[16] = {
//0 1 2 3 4 5 6 7 8
BLACK, BRIGHTRED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE,
// 9 A B C D E F
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE
};
entonces mi framebuffer es una matriz como esa:
#define fbWidth 256
#define fbHeight 200
char frameBuffer[fbWidth*fbHeight/2]; // 256*200*4bit
Intento intercambiar los búferes dobles así:
for(i=0;i< fbWidth*fbHeight/2;i++)
{
u16 color = LUT[frameBuffer[i]];
*(__IO uint16_t *) (Bank1_LCD_D)= color;
}
y para escribir en el backbuffer:
// color is 2
frameBuffer[fbWidth * y + x] = color;
El problema es que obtengo menos resolución de pantalla debido a que trunqué el ancho del búfer de marco * alto / 2. Parece que no implementé correctamente el concepto de tabla de colores de búsqueda.
Tu problema aquí es que estás trabajando en bytes, pero el framebuffer está conceptualmente en nibbles.
Digamos que tiene una pantalla de 256x200, entonces tiene un framebuffer de 256x200 nibbles, de 256x200/2 bytes. Eso está bien, y lo que tienes.
Luego necesita traducir sus coordenadas X/Y a una ubicación de bytes de framebuffer. Para eso necesitas trabajar con la mitad del ancho, o la mitad de la altura. Por ejemplo, la ubicación 10,20 equivaldría a la mitad del valor de 20 anchos + 10 bytes. Eso sería (20 * 256 + 10) / 2 = 1285.
Ahora, estás a mitad de camino. Sabes en qué parte del framebuffer está tu píxel elegido, pero no en qué mitad del byte. Para eso, debe mirar la ubicación completa del píxel y ver si es par o impar. 20 * 156 + 10 = 2570. Ese es un número par (2570 y 1 = 0; el LSB está establecido en 0, por lo que es par), por lo que solo desea modificar el nibble más bajo del valor (si fuera impar, usted modificaría el nibble más alto; por supuesto, podría almacenarlos al revés; ver más adelante).
Entonces, leería el valor actual de la matriz, enmascararía el nibble que desea modificar para que sea todo 0, luego superponga el nuevo valor.
Digamos que el byte actualmente contiene 0b10011100, lo haría Y con 0b11110000 para dar como resultado 0b10010000. Luego, O ese resultado con su nuevo valor de píxel, digamos 2, para dar como resultado 0b10010010.
Si estuviera modificando el nibble superior, primero necesitaría cambiar su valor de color 4 bits a la izquierda para convertirlo en 0b00100000 en lugar de 0b00000010, luego o con el nibble superior enmascarado del byte.
Luego vuelves a escribir el byte.
Ahora, mostrar el framebuffer en la pantalla es una tarea igualmente onerosa:
Debe tomar cada byte del framebuffer y dividirlo en dos partes. Desplace hacia la derecha el nibble superior 4 bits para convertirlo en un número entre 0 y 15. Busque el color del nibble inferior y colóquelo en la pantalla. Luego haga lo mismo con el nibble superior colocándolo en la pantalla en el siguiente píxel. Luego avanza al píxel siguiente, por lo que se ha movido en 2 píxeles en total.
Tenga en cuenta lo anterior: si almacenó el par en el nibble superior y el impar en el nibble inferior, solo generaría los píxeles en el orden opuesto: superior y luego inferior.
¿Claro como el barro ahora?
gbulmer
fbWidth*fbHeight/2
. Intente hacer funcionar un solo framebuffer, haciendo que el código sea tan simple como práctico.Ahmed Saleh
gbulmer