Driver de un controlador gráfico -...

94
Driver de un controlador gráfico TITULACIÓ: Enginyeria en Automàtica i Electrònica Industrial AUTOR: Víctor García González DIRECTOR: Ernest Gil Dolcet DATA: 04 / 07.

Transcript of Driver de un controlador gráfico -...

Page 1: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

Driver de un controlador gráfico

TITULACIÓ: Enginyeria en Automàtica i Electrònica Industrial

AUTOR: Víctor García González DIRECTOR: Ernest Gil Dolcet

DATA: 04 / 07.

Page 2: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

2

Índice Índice ..................................................................................................................................... 2 Lista de Figuras ..................................................................................................................... 4 Lista de Tablas....................................................................................................................... 5 1. Objetivos y Antecedentes .................................................................................................. 6 2. Idea Básica......................................................................................................................... 7

2.1. Estructura General Del Sistema.................................................................................. 8 2.2. Aplicación................................................................................................................... 9 2.3. Descripción del Protocolo de Comunicaciones ........................................................ 10

3. Especificación del Proyecto............................................................................................. 12 3.1. Objetivos del Proyecto. ............................................................................................ 13 3.2. Requisitos del Sistema.............................................................................................. 15

4. Resolución del Proyecto .................................................................................................. 16 4.1. Estructura General del Proyecto ............................................................................... 17 4.2. Estructura de las Capas Software ............................................................................. 18

4.2.1. Primera Capa: Abstracción del Microcontrolador............................................. 19 4.2.2. Segunda Capa: Abstracción del Controlador de LCD’s.................................... 22 4.2.3. Tercera Capa: Librería Gráfica.......................................................................... 24

4.3. Esquema de Llamadas entre Funciones y Diagramas de Flujo ................................ 28 4.3.1. Primera Capa: Capa de Abstracción del Microcontrolador............................... 29

Esquema de llamadas entre funciones de la primera capa....................................... 29 Diagrama de flujo de la función ‘ComFrmTx 0/1 ( )’............................................. 31 Diagrama de flujo de la función ‘ComAttUartRx 0/1 ( )’ ....................................... 32

4.3.2. Segunda Capa: Capa de Abstracción del Controlador de Display. ................... 33 Esquema de llamadas entre funciones de la segunda capa...................................... 33 Diagrama de flujo de la función ‘EpsonCfg ( )’...................................................... 34

4.3.3. Tercera Capa: Librería Gráfica.......................................................................... 35 Esquema de llamadas entre funciones de la tercera capa. ....................................... 35 Diagrama de flujo de la función ‘ShowFullWindowText ( )’ ................................. 37 Diagrama de flujo de la función ‘SetBmp ( )’ ......................................................... 39 Diagrama de flujo de la función ‘SetRectangulo ( )’............................................... 41

4.4. Creación de las Fuentes de Letra.............................................................................. 43 5. Programación................................................................................................................... 45

5.1. Funciones de la Primera Capa .................................................................................. 46 5.2. Funciones de la Segunda Capa ................................................................................. 55 5.3. Funciones de la Tercera Capa................................................................................... 58

6. Análisis ............................................................................................................................ 70 6.1. Comprobación del Software de Comunicaciones..................................................... 71 6.2. Velocidad de Escritura de Texto .............................................................................. 72 6.3. Velocidad de Dibujo de Bitmaps.............................................................................. 73 6.4. Velocidad de Dibujo de Rectángulos. ...................................................................... 74 6.5. Velocidad de Dibujo de Ventanas ............................................................................ 75 6.6. Demo ........................................................................................................................ 76

7. Ampliaciones y Mejoras.................................................................................................. 80 7.1. Posibles Mejoras en la Escritura de Texto................................................................ 81 7.2. Mejoras en la Muestra en Pantalla de Bitmaps y Rectángulos................................. 82 7.3. Uso de Formatos de Imagen con Compresión.......................................................... 83 7.4. Asociación de Funciones Gráficas a Dispositivos de Entrada. ................................ 84 7.5. Uso de los Puertos de Comunicación Serie .............................................................. 85

Page 3: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

3

7.6. Implementación del Protocolo USB......................................................................... 86 8. Entorno de Trabajo .......................................................................................................... 87 9. Conclusiones.................................................................................................................... 88 10. Bibliografía.................................................................................................................... 89 Anexo I. Información sobre Ficheros BMP......................................................................... 90 Anexo II. Información sobre Imágenes JPEG..................................................................... 92

Page 4: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

4

Lista de Figuras Figura 1. Estructura general del sistema............................................................................... 8 Figura 2. Estructura de las tramas de comunicación. ......................................................... 10 Figura 3. Llamadas entre funciones para el envío de tramas. ............................................ 29 Figura 4. Llamadas entre funciones para la recepción de tramas....................................... 30 Figura 5. Diagrama de flujo de la función ComFrmTx0/1(). ............................................. 31 Figura 6. Diagrama de flujo de la función ConAttUartRx0/1() ......................................... 32 Figura 7. Esquema de llamadas entre las funciones de la segunda capa............................ 33 Figura 8. Diagrama de flujo de la función EpsonCfg() ...................................................... 34 Figura 9. Esquema de llamadas a función desde SetRectangulo()..................................... 35 Figura 10. Esquema de llamadas a función desde SetBmp() y WrDispText()................... 35 Figura 11. Esquema de llamadas a función desde las funciones de ventana...................... 36 Figura 12. Diagrama de flujo de la función ShowFullWindowText () 1/2. ....................... 37 Figura 13. Diagrama de flujo de la función ShowFullWindowText () 2/2. ....................... 38 Figura 14. Diagrama de flujo de la función SetBmp () 1/2 . .............................................. 39 Figura 15. Diagrama de flujo de la función SetBmp () 2/2. ............................................... 40 Figura 16. Diagrama de flujo de la función SetRectangulo() 1/2....................................... 41 Figura 17. Diagrama de flujo de la función SetRectangulo() 2/2....................................... 42 Figura 18. Imagen con la fuente Lucida Console, tamaño 10. ........................................... 43 Figura 19. Fuentes empleadas en el proyecto..................................................................... 72 Figura 20. Imagen original ................................................................................................. 92 Figura 21. Imagen JPEG con una compresión excesiva..................................................... 93 Figura 22. Imagen JPEG con una compresión extrema. .................................................... 93

Page 5: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

5

Lista de Tablas Tabla 1. Valores de codificación. ....................................................................................... 11 Tabla 3. Velocidades de escritura en pantalla. ................................................................... 72 Tabla 4. Velocidades obtenidas en el dibujo de bitmaps.................................................... 73 Tabla 5. Velocidades obtenidas en el dibujo de rectángulos. ............................................. 74 Tabla 6. Formato de un bitmap........................................................................................... 90 Tabla 7. Información de la cabecera................................................................................... 90 Tabla 8. Campo de propiedades de un bitmap.................................................................... 90 Tabla 9. Estructura de la paleta........................................................................................... 91

Page 6: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

6

1. Objetivos y Antecedentes Se trata de la programación del driver de un dispositivo controlador de pantallas

LCD que se encuentra dentro de un sistema empotrado, el modelo de controlador de pantallas es el S1D13505 de Epson. El driver parte desde la abstracción de las especificaciones hardware, independizando el driver programado del microcontrolador implementado, hasta el nivel gráfico.

Además del desarrollo software se tiene que colaborar en el diseño del esquemático del PCB del sistema, dentro de la parte correspondiente al sistema gráfico.

En cuanto a la parte software concluye con la creación de una pequeña demo que muestra los resultados obtenidos.

Este proyecto forma parte de otro proyecto más amplio del CITEE, ha sido desarrollado en sus propias instalaciones, se trata de un proyecto de prospección tecnológica de dispositivos adecuados para control de displays del mercado. El software generado en este proyecto está catalogado como confidencial. Por este motivo se explicará la estructura, filosofía y funcionalidad del software pero no se mostrará el código fuente, a excepción del código de la demo expuesta en el apartado ‘6. Análisis’.

Page 7: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

7

2. Idea Básica En este apartado se describe la idea básica del sistema en cuanto a estructura y aplicaciones posibles. También se ofrece una descripción del protocolo de comunicaciones implementado en el sistema. Se distinguen los siguientes apartados:

• Estructura general del sistema • Aplicación • Descripción del protocolo de comunicaciones.

Page 8: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

8

2.1. Estructura General Del Sistema Tal como se muestra en la figura 1 el sistema consta de un PCB que integra

básicamente un microcontrolador y un controlador de display. El controlador de display controla una pantalla LCD. Por otra parte se cuenta con la conexión a ordenador mediante un debugger durante la fase de desarrollo, y una conexión eventual mediante puerto serie o USB para permitir incorporar nuevas imágenes, fuentes de letra u otros paquetes de información extra. Por último se encuentran los dispositivos de entrada del sistema, para permitir la interacción con el usuario.

Figura 1. Estructura general del sistema.

Pantalla LCD

Microcontrolador Philips LPC2294

Controlador de display Epson S1D13A05

Debugger IAR L-Link-KS JTAG

Puerto USB

Puertos serie Com0/1

Puertos serie Com0/1

Puerto USB

Conexión eventual

Inversor AC/DC CXA-P1212B-WJL

220 v

Fase desarrollo

PCB del sistema

PC

Teclado, ratón, pantalla táctil o cualquier dispositivo de entrada para interacción con el usuario

Mem RAM y ROM

Page 9: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

9

2.2. Aplicación Todo aquel proceso donde se necesite una visualización de estado, resultados o

cualquier tipo de dato. Por la resolución de pantalla que puede ser cubierta se tendrán unas limitaciones

que descartarán al sistema desarrollado para el control de grandes pantallas, por el otro extremo tampoco será lógico usarlo para visualizar tan solo dígitos en máquinas expendedoras por ejemplo. Su uso será enfocado para visualizaciones gráficas de nivel ‘medio’ donde no basten los carácteres alfanuméricos pero tampoco haga falta tratar con unos gráficos asombrosos.

Los sistemas de visualización con pantallas LCD con el nivel gráfico implementado en este proyecto se encuentran en multitud de dispositivos industriales y de consumo, así como electrodomésticos, equipos de telecomunicación, médicos, de audio, etc.

Page 10: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

10

2.3. Descripción del Protocolo de Comunicaciones Las comunicaciones del sistema se rigen mediante un protocolo que se explica a continuación. La comunicación se realiza mediante el intercambio de tramas. Las tramas contienen un número de datos que puede oscilar desde 0 hasta 255.

La comunicación tiene sistema de detección de errores pero no de corrección. Existen tres valores de byte reservados, son el 0x01, 0x04 y 0x1B. El 0x01 se

reserva para el campo de comienzo de trama, el 0x04 para el campo de final de trama y el 0x1B para indicar que el siguiente byte está codificado. Debido a que existen valores reservados los bytes de la trama que tengan el valor de alguno de los valores reservados se deberán codificar para poder ser enviados. La codificación consiste en añadir un byte extra con el valor 0x1B y después el valor codificado del byte. La codificación se explica más adelante en mayor detalle. El formato de la trama se puede observar en la figura 2. SOF NumDataBytes DataByte 1 DataByte 2 ……DataByte n ChkSum EOF

Figura 2. Estructura de las tramas de comunicación.

A continuación se explican los diferentes campos de la trama: • SOF: (Start Of Frame) comienzo de trama, su valor es siempre de 0x01. Es

el único campo que puede adoptar este valor, es un valor reservado, esto asegura que cada vez que se reciba un 0x01 se sepa sin duda alguna que es el comienzo de una trama.

• NumDataBytes: (Number Of Data Bytes) número de bytes de datos, su valor puede ir desde 0 hasta 255, lo que limita a 255 el número máximo de bytes de datos por trama.

• DataByte1…255: Byte de datos, son los bytes que contienen la información de la trama. El número de estos bytes viene marcado por el campo NumDataBytes.

• ChkSum: (Check Sum) comprobación de la suma. Para disponer de un método de detección de errores en la comunicación se ha añadido este campo. Su valor debe ser la suma de todos los bytes de trama anteriores a él, incluyendo el byte de SOF. Si el valor de la suma es igual o superior a 256 se cogen tan solo los ocho bits menos significativos de la suma. Ya en la recepción de la trama, si difiere el ChkSum calculado durante la recepción del ChkSum recibido en la propia trama significará que se ha recibido una trama incorrecta.

• EOF: (End Of Frame) final de trama, indica que se ha llegado al final de la trama. Su valor es siempre 0x04. Es el único campo que puede adoptar este valor, es un valor reservado, esto asegura que cada vez que se reciba un 0x04 se sepa sin duda alguna que es final de una trama.

En cuanto a la codificación de los bytes, están únicamente exentos de codificación

los campos de SOF y EOF. Los demás, incluyendo el propio ChkSum deben ser codificados. Cuando uno de los bytes de la trama (excepto los exentos de codificación) valga 0x01, 0x04 o 0x1B se substituirá por dos bytes. El primer byte será el indicador de codificación, que es el byte 0x1B, y el siguiente byte será el que corresponda según lo expuesto en la tabla 1.

Page 11: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

11

Valor a codificar Valor codificado 0x01 0xFF 0x04 0xFE 0x1B 0xFD

Tabla 1. Valores de codificación. Debido a la codificación puede aumentar la longitud de la trama. En la recepción de

tramas se deberá efectuar para la descodificación de las tramas la operación contraria a la realizada en la construcción de la trama. Cuando se reciba el byte indicador de codificación éste se deberá interpretar pero no guardar, y al recibir el siguiente byte se guardará según la tabla 1 el valor a codificar en substitución del valor codificado.

Page 12: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

12

3. Especificación del Proyecto En este apartado se exponen por una parte los objetivos marcados al comienzo del

proyecto y por otra se explican los requisitos hardware de los que ha de disponer el sistema sobre el que se puede aplicar este proyecto.

En el subapartado ‘3.1. Objetivos del Proyecto’ se expondrán principalmente los objetivos software que se pretenden conseguir. La parte software es sin duda la más importante y visible de este proyecto pero no hay que olvidar el trabajo de definición del hardware cuyo estado a principio de proyecto era de idea elaborada pero no concretada.

El hardware del sistema abarca más funcionalidades de las que se tratan en este proyecto, por eso mismo este proyecto se centra en la definición de la parte relacionada con la funcionalidad gráfica. El desarrollo hardware del proyecto incluye el estudio de las diferentes posibilidades de modelos de dispositivos a implementar en el sistema relacionados con la función gráfica y el estudio de la documentación de éstos para la definición del esquemático del PCB del sistema. Los dispositivos implicados en la función gráfica son el microcontrolador, el controlador de display, el display y la alimentación de display.

Page 13: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

13

3.1. Objetivos del Proyecto. Se pretende crear un driver software para un controlador de pantallas LCD,

concretamente para el modelo S1D13A05 de Epson. Este controlador ha de estar implementado dentro de un sistema empotrado con sus lógicas limitaciones hardware, propias de este tipo de sistemas. Esto lleva a la necesidad de crear un software que funcione relativamente rápido y que no sea excesivamente extenso.

Para el desarrollo de una funcionalidad gráfica del sistema se sabe que antes se deberá trabajar con niveles software inferiores. Tanto en el nivel más bajo que corresponde al propio manejo del microcontrolador del sistema, modelo LPC2294 de Philips, como con la interacción entre el microcontrolador y el chip S1D13A05 de Epson.

Por lo explicado anteriormente se entiende que el software deberá estar dividido en varios estratos los cuales se deberán diferenciar e independizar al máximo posible unos de otros. Un estrato corresponderá al manejo del microcontrolador, otro a la interacción entre el microcontrolador y el controlador de LCD, y por último el que propiamente da nombre al proyecto que será la parte gráfica.

Los objetivos que se pretenden conseguir en la parte gráfica no son muy ambiciosos. Esto es debido a que los resultados gráficos serán tan sólo la parte visual de un trabajo que deberá partir desde niveles inferiores, y por tanto, el trabajo en su globalidad será más amplio de lo que indicarán a primera vista tan solo los resultados gráficos.

Los objetivos gráficos perseguidos son los siguientes: - Configuración total de la pantalla que incluye: tamaño de pantalla útil,

modo gráfico de color o monocromo y selección de profundidad de color.

- Escritura de texto en pantalla con varias fuentes de letra seleccionables. - Dibujo de formas simples como puntos, rectas y rectángulos. - Creación de ventanas con texto en su interior que deben poder ser

activadas o desactivadas. Al ser activadas deberán pasar al primer plano de la pantalla.

- Dibujo en pantalla de bitmaps. Para conseguir los objetivos relacionados con escritura hay un trabajo

independiente a la programación del sistema. Este trabajo es la creación de los juegos de fuentes de letra a usar. Como se explicará más ampliamente en el apartado ‘4. Resolución de Proyecto’ cada juego de fuentes de letra ha sido extraído a partir de la información de una imagen que contiene los caracteres deseados, creada mediante un programa editor de gráficos. Esta imagen posteriormente se usa e interpreta para la creación de un array que contiene en cada posición la información para el dibujo de un carácter ASCII.

En cuanto a la parte hardware, el sistema no estaba definido al comienzo del proyecto, por lo que se debía diseñar con una serie de requisitos que se explican a continuación.

El dispositivo controlador de pantallas LCD que ha sido seleccionado para el sistema, S1D13A05 de Epson, funciona básicamente con la manipulación de registros internos y con la asignación de valores en la memoria de display de la que dispone. Tanto los registros como la memoria de display son directamente direccionables mediante el bus de direcciones que implementa el chip, también cuenta por supuesto con un bus de datos bidireccional independiente al de direcciones para la lectura y escritura de registros y memoria. Todo esto lleva a la necesidad de implementar el sistema con un microcontrolador que disponga de un bus de direcciones y otro de datos orientados hacia el exterior. En el caso del microcontrolador del sistema se cuenta con un módulo específico para la interacción con elementos externos ‘memory maped’. Este módulo se llama EMC

Page 14: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

14

(Controlador de Memoria Externa), servirá tanto para controlar el S1D13A05 como las memorias RAM i Flash que se le quieran añadir al sistema.

Page 15: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

15

3.2. Requisitos del Sistema Este proyecto ha sido desarrollado para un controlador de display específico, el S1D13A05 de Epson. Por tanto el primer requisito del sistema es que se implemente este chip. Aunque como se verá más adelante mucho software podría ser aprovechado si se cambiase de dispositivo debido al desarrollo por capas del software.

Otro requisito del sistema como se ha explicado en el subapartado anterior es que se implemente un microcontrolador que disponga de bus de direcciones y de datos orientados hacia el exterior, debido a la forma de funcionar del dispositivo controlador de display. Si se cumple este requisito pero no se implementa exactamente el mismo microcontrolador usado en este proyecto, modelo LPC2294 de Philips, el software creado referente a la parte gráfica sería aprovechable pero se debería de tratar el manejo del nuevo microcontrolador. La posibilidad de un fácil cambio de microcontrolador es debida una vez más al desarrollo por capas del software.

Page 16: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

16

4. Resolución del Proyecto La resolución de este proyecto ha procurado ser desde un primer momento muy

modular y jerárquica. Con este fin el software generado se ha desarrollado en capas independientes. Cada capa corresponde a una jerarquía con la particularidad que cada una hace uso de la capa inmediatamente inferior pero no de la superior ni de la que está dos escalones por debajo.

El objetivo de los dos primeros niveles es el de independizar las capas superiores respecto al hardware que tratan sus funciones, por lo que se puede decir que su finalidad es la de abstracción del hardware.

En los siguientes subapartados se explica más en concreto la estructura del proyecto así como cada capa por separado.

Por otra parte como se explica en el subapartado ‘4.4. Creación de las Fuentes de Letra’ se ha tenido que desarrollar un trabajo independiente al software del sistema para la obtención de las fuentes de letra que usa la librería gráfica.

Page 17: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

17

4.1. Estructura General del Proyecto Como se ha explicado anteriormente la estructura del proyecto es jerárquica. En

esta jerarquía se pueden distinguir tres niveles o capas. En su desarrollo se ha buscado la independencia de sus diferentes capas lo máximo posible unas de otras.

Las tres capas de software de las que se compone el software del proyecto son las siguientes:

• 1ª capa: Capa de abstracción del microcontrolador • 2ª capa: Capa de abstracción del controlador de LCD’s • 3ª capa: Librería gráfica

Page 18: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

18

4.2. Estructura de las Capas Software Ya se ha mencionado en la introducción de este apartado que se tienen tres capas de

software bien diferenciadas. En este subapartado se describirá más en detalle cual es la filosofía de cada una de las capas software, también se explicarán las funcionalidades cubiertas por cada una, así como las funciones relacionadas con la funcionalidad mencionada.

Page 19: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

19

4.2.1. Primera Capa: Abstracción del Microcontrolador La intención de esta primera capa es abstraer al usuario del microcontrolador que se

está utilizando. En este proyecto se ha implementado un microcontrolador Philips de 32bits, modelo LPC2294, para más información acerca del microcontrolador consultar en www.nxp.com.

Esta capa es específica para el microcontrolador mencionado, si se cambiase de modelo se debería programar esta capa de nuevo.

En cuanto a la funcionalidad cubierta para la abstracción del microcontrolador se distinguen los siguientes puntos:

• Configuración de los pines y parámetros del microcontrolador para su correcto funcionamiento dentro de la placa implementada. Se tiene en cuenta en este apartado la configuración de pines para comunicación con memorias RAM, Flash y el programador JTAG, así como la configuración de sus respectivos buses.

o Si se cambiasen configuraciones de la placa sería probable que se

tuvieran que hacer también modificaciones en este apartado de configuración

o Funciones relacionadas con esta funcionalidad concreta:

LPC2294SystemInit ( )

• Manejo y configuración de los temporizadores.

o Se incluyen los siguientes subapartados: Configuración de los temporizadores. Puesta en marcha de los temporizadores. Parada de los temporizadores.

o Funciones relacionadas con esta funcionalidad concreta:

TimSet () TimStart() TimStop()

• Manejo de los leds del sistema.

o Se incluyen los siguientes subapartados: Configuración de los pines correspondientes a los leds. Encendido y apagado de los leds.

o Funciones relacionadas con esta funcionalidad concreta:

LedPinsCfg() LedOn() LedOff()

• Ajuste de PLL para obtener la frecuencia deseada en el microcontrolador.

o Funciones relacionadas con esta funcionalidad concreta: PllSetup()

Page 20: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

20

• Manejo de los vectores de interrupción.

o Se incluyen los siguientes subapartados: Asignación de la función a llamar por el vector de

interrupción seleccionado. Reset del vector seleccionado. Consulta de la función asignada al vector de interrupción

seleccionado.

o Funciones relacionadas con esta funcionalidad concreta: VectSet() VectRst() VectGet()

• Atención a las interrupciones de los timers y de los puertos serie. Una vez

salta una interrupción una función es llamada para atender dicha interrupción.

o Funciones relacionadas con esta funcionalidad concreta:

AttInt_UART0 () AttInt_UART1 () AttInt_Timer0 () AttInt_Timer1 ()

• Configuración, apertura y cierre de los puertos serie del sistema.

o Funciones relacionadas con esta funcionalidad concreta: ComCfg () ComOpen () ComClose ()

• Transmisión de tramas por los puertos de comunicación serie.

o Se incluyen los siguientes subapartados: Inicio de la transmisión de las tramas. Envío del primer byte

de la trama, ya que el resto de bytes se va enviando mediante el salto de interrupción según se va vaciando el buffer de transmisión.

Efectuación de la orden de envío del resto de los bytes de la trama después del salto de la interrupción.

Envío individual de cada byte de la trama.

o Funciones relacionadas con esta funcionalidad concreta: ComFrmTx () ComByteTx0 () ComByteTx1 () ComAttUartTx0 () ComAttUartTx1 ()

Page 21: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

21

• Recepción de tramas por los puertos de comunicación serie. o Se incluyen los siguientes subapartados:

Recepción de la trama. Decodificación de la trama. Lectura de los bytes de datos de la trama. Uso de los bytes de datos de la trama.

o Funciones relacionadas con esta funcionalidad concreta:

ComAttUartRx0 () ComAttUartRx1 () ComRdRx () ComRxApp () funApp0 () funApp1 ()

• Consulta del estado de las comunicaciones .

o Funciones relacionadas con esta funcionalidad concreta: ComGetSt ()

Page 22: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

22

4.2.2. Segunda Capa: Abstracción del Controlador de LCD’s La intención de esta segunda capa es abstraer al usuario del dispositivo controlador

de pantallas LCD’s que se está utilizando. El dispositivo controlador de LCD’s que se ha implementado en este proyecto es el modelo S1D13A05 de Epson, para obtener más información acerca de este dispositivo consultar en www.erd.epson.com.

Esta capa es específica para el dispositivo mencionado, si se cambiase de modelo se debería programar de nuevo.

En cuanto a la funcionalidad cubierta para la abstracción del controlador de display se hayan los siguientes puntos:

• Configuración e inicialización del dispositivo.

o Se incluyen los siguientes subapartados: Ajuste de parámetros, velocidades y estados de espera del

bus de comunicaciones entre el microcontrolador y el controlador de LCD’s

Inicialización de la LUT. Configuración inicial de todos los registros internos del

dispositivo para su correcto funcionamiento dentro del sistema.

Puesta a cero de toda la memoria del display, lo que se traduce en una pantalla completa en negro.

Inicialización de punteros globales necesarios para otras muchas funciones de esta capa.

o Funciones relacionadas con esta funcionalidad concreta:

EpsonCfg ()

• Inicialización del dispositivo. Las funciones pertenecientes a esta funcionalidad son llamadas por la función de configuración arriba explicada, por lo que sus funciones serán puntos comunes a los mencionados anteriormente.

o Se incluyen los siguientes subapartados:

Inicialización de la LUT. Configuración inicial de todos los registros internos del

dispositivo para su correcto funcionamiento dentro del sistema.

Puesta a cero de toda la memoria del display, lo que se traduce en una pantalla completa en negro.

o Funciones relacionadas con esta funcionalidad concreta:

halInitRegisters () halClearVmem () halInitLUT ()

• Acceso a memoria de display.

o Se incluyen los siguientes subapartados: Lectura de memoria en formato de 8, 16 o 32 bits

Page 23: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

23

Escritura de memora en formato de 8, 16 o 32 bits

o Funciones relacionadas con esta funcionalidad concreta: halReadDisplay8 ( ) halReadDisplay16 ( ) halReadDisplay32 ( ) halWriteDisplay8 ( ) halWriteDisplay16( ) halWriteDisplay32 ( )

• Acceso a registros del dispositivo controlador de LCD’s .

o Se incluyen los siguientes subapartados: Lectura de registros en formato de 8, 16 o 32 bits Escritura de registros en formato de 8, 16 o 32 bits

o Funciones relacionadas con esta funcionalidad concreta:

halReadReg8 ( ) halReadReg16 ( ) halReadReg32 ( ) halWriteReg8 ( ) halWriteReg16( ) halWriteReg32 ( )

Page 24: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

24

4.2.3. Tercera Capa: Librería Gráfica Esta tercera capa se compone de una librería gráfica que es independiente del hardware que se utilice, siempre y cuando tenga el mismo tipo de estructura de memoria que el modelo de dispositivo usado en este proyecto (S1D13A05). La estructura de memoria del S1D13A05 se basa en que en la memoria representa secuencialmente desde la posición 0 hasta la última los píxels de la pantalla, correspondiendo una misma posición de memoria a diferentes píxeles según los bits por píxel activos en el sistema. Es de suponer que según los bits por píxel activos sobrará memoria, así como el caso contrario en el que se tenga seleccionada la mayor profundidad de color posible con la que tan sólo se podrá representar tamaños de pantalla inferiores al máximo.

En cuanto a la funcionalidad cubierta en esta capa se hayan los siguientes apartados:

• Configuración de display.

o Se incluyen los siguientes subapartados: Configuración del dispositivo controlador de display mediante la

llamada a la función correspondiente, de la segunda capa. Creación de la ventana de escritorio, que es la ventana que se

tendrá por defecto en pantalla al iniciar el sistema. Preinicialización del resto de ventanas poniendo a cero las

variables oportunas.

o Funciones relacionadas con esta funcionalidad concreta: CfgDisplay ( )

• Ajuste y consulta de colores.

o Se incluyen los siguientes subapartados: Ajuste del color de escritura Consulta de color de escritura activo Ajuste del color de fondo. El color de fondo se usa para el dibujo

de rectas, rectángulos, píxels sueltos, etc. Consulta del color de fondo activo.

o Funciones relacionadas con esta funcionalidad concreta:

SetColor ( ) GetColor ( ) SetColorBck ( ) GetColorBck ( )

• Dibujo de píxels, líneas y rectángulos.

o Se incluyen los siguientes subapartados: Dibujo de píxels sueltos Dibujo de líneas tanto horizontales, verticales como diagonales. Dibujo de rectángulos, esta función puede usarse tanto para

dibujar rectángulos independientes a las ventanas existentes como para crear el rectángulo de fondo de una ventana. Si el rectángulo definido es muy pequeño se dibujará

Page 25: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

25

descomponiéndolo en líneas y a continuación píxel a píxel, pero para tamaños normales y grandes el rectángulo se dibujará escribiendo words enteros a la memoria de display. El objetivo de escribir en words es el de aprovechar al máximo el ancho de bus entre el microcontrolador y el dispositivo controlador de pantalla.

o Funciones relacionadas con esta funcionalidad concreta:

SetLine ( ) SetRectangulo ( ) SetPixel ( ) _Pixel1bpp () _Pixel2bpp () _Pixel4bpp () _Pixel8bpp () _Pixel16bpp ()

• Funciones de texto directamente orientadas a pantalla. Directamente orientadas

a pantalla significa que son independientes de las ventanas. Su función por ejemplo puede ser la de mostrar algo momentáneamente en pantalla independientemente de la ventana que esté activa en un preciso momento.

o Se incluyen los siguientes subapartados:

Selección de la fuente activa para escritura. Se dispone de un juego de fuentes a elegir.

Escritura de texto en pantalla con el color y tipo de fuentes activas en el momento de la llamada a la función.

o Funciones relacionadas con esta funcionalidad concreta:

SetFont ( ) WrDispText ( )

• Dibujo en pantalla de bitmaps. Esta función puede dibujar BMP’s directamente

a pantalla independientes a las ventanas si se llama a la función directamente, o también puede ser llamada mediante la función de configuración de ventanas para formar parte del fondo de una ventana. El bitmap se escribe en words enteros a la memoria de display. El objetivo de escribir en words es el de aprovechar al máximo el ancho de bus entre el microcontrolador y el dispositivo controlador de pantalla.

o Funciones relacionadas con esta funcionalidad concreta:

SetBmp ( )

• Funciones relacionadas con la creación, configuración y manejo de ventanas.

o Se incluyen los siguientes subapartados: Dibujo de rectángulo de fondo de pantalla. Dibujo del marco de la ventana. Creación y configuración de ventanas, siendo seleccionable el

tipo de fuente de la ventana, tamaño de ventana, posición inicial,

Page 26: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

26

color de letra y de fondo, texto inicial e incluyendo la posibilidad de añadir un bitmap de fondo centrado en la ventana.

Impresión del texto correspondiente a la ventana tratada con adaptación automática al tamaño de la ventana.

Activación de ventanas. Añadido de texto a la ventana activa. Desplazamiento del texto para visualizar las partes de texto no

visibles, tanto por arriba como por abajo. Maximización de ventana con adaptación automática del texto a

las nuevas dimensiones de la ventana. Minimización de ventana con adaptación automática del texto a

las nuevas dimensiones de la ventana. Redimensionamiento de ventana con adaptación automática del

texto a las nuevas dimensiones de la ventana. Desplazamiento de ventana con la protección de máximo

desplazamiento permitido hasta los bordes de la pantalla.

o Funciones relacionadas con esta funcionalidad concreta: SetRectangulo ( ) DrawFrame ( ) SetBmp ( ) ShowFullWindowText ( ) SetWindowActive ( ) SetWindowText ( ) AddText ( ) MoveUpText ( ) MaxWindow ( ) MinWindow ( ) MoveWindow ( ) RedimensionWindow ( )

o Para poder cubrir toda la funcionalidad de las ventanas descrita se

dispone de una estructura de datos asociada a cada una de las ventanas del sistema. Esta estructura contiene información sobre:

El estado de inicialización de la ventana. Según su valor se sabe si la ventana en cuestión había sido inicializada anteriormente.

La coordenada horizontal actual de la esquina superior izquierda. La coordenada vertical actual de la esquina superior izquierda. La coordenada horizontal actual de la esquina inferior derecha. La coordenada vertical actual de la esquina inferior derecha. Valores de todas las coordenadas en su estado original. El estado

original es el estado no maximizado de la ventana. Para el resto de casos el valor de las coordenadas actuales y originales es el mismo.

Puntero a la cadena de caracteres a escribir en la ventana. Color de la fuente asociada a la ventana. Color de fondo de la ventana. Puntero al buffer de la fuente de texto asociada a la ventana. Tamaño horizontal y vertical de la fuente de texto asociada a la

ventana.

Page 27: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

27

Índice del último carácter de la cadena de texto a escribir. Si vale cero no quiere decir necesariamente que no haya nada que escribir, sino que a priori no se sabe donde acaba la cadena de caracteres a escribir.

Número de líneas que está desplazado el texto en su presentación en la ventana, para visualizar texto anteriormente no visible.

Puntero a la imagen que aparecerá centrada en el fondo de la ventana. Si vale cero querrá decir que no hay imagen a mostrar.

Page 28: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

28

4.3. Esquema de Llamadas entre Funciones y Diagramas de Flujo En este subapartado se muestran las conexiones que existen entre las diferentes

funciones de cada capa software para clarificar la estructura que forman éstas dentro de cada capa.

También se muestra el diagrama de flujo de las funciones más complicadas en cuanto a estructura.

Para más información sobre las funciones consultar el apartado ‘5. Programación’ donde se encuentra una explicación más detalla de cada una de las funciones de las tres capas de software de las que consta el sistema.

Page 29: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

29

4.3.1. Primera Capa: Capa de Abstracción del Microcontrolador

Esquema de llamadas entre funciones de la primera capa En la figura 3 se muestran las diferentes llamadas entre funciones que se efectúan para la transmisión de tramas.

Figura 3. Llamadas entre funciones para el envío de tramas.

Para que se cumpla el esquema presentado en la figura 3 tal y como se muestra

previamente se deben haber asignado las funciones ComAttUartTx0/1() como funciones a llamar por AttInt_UART0/1() mediante los punteros a función pasados en ComCfg() en caso de interrupción de transmisión (buffer de transmisión vacío).

ComFrmTx ( )

ComAttUartTx0( )

ComAttUartTx1( )

AttInt_UART0( )

AttInt_UART1( )

ComByteTx0 ( ) ComByteTx1 ( )

Mediante el salto de int. de buffer de

transmisión vació

Envío del 1er byte

Envío del resto de bytes

INICIO DE TRANSMISIÓN

DE TRAMAS

¿Es el byte de final de

trama?

Desactiva la int. de buffer de tx. vacío Sí

No

Page 30: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

30

En la figura 4 se muestran las diferentes llamadas entre funciones que se efectúan para la recepción de tramas.

Figura 4. Llamadas entre funciones para la recepción de tramas.

Para que se cumpla el esquema presentado en la figura 4 tal y como se muestra

previamente se deben haber asignado las funciones ComAttUartRx0/1() como funciones a llamar en caso de interrupción de recepción por AttInt_UART0/1() mediante los punteros a función pasados en ComCfg().

ComRdRx ( )

ComAttUartRx0( ) ComAttUartRx1( )

funApp0( ) funApp1( )

AttInt_UART0( ) AttInt_UART1( )

RECEPCIÓN DE TRAMAS

Salto de int. de buffer de recepción lleno

Recepción de trama completada con éxito

Page 31: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

31

Diagrama de flujo de la función ‘ComFrmTx 0/1 ( )’ En la figura 5 se muestra el diagrama de flujo de la función ConFrmTx0/1 ().

Figura 5. Diagrama de flujo de la función ComFrmTx0/1().

Se retorna de la función devolviendo un cero en señal de la negación a la petición de envío de trama

Construcción de la trama a enviar en el buffer de envío de la función

¿Hay otro envío anterior de trama activo?

No

Se da valor al byte de comienzo de trama

Se da valor al byte que indica el número de bytes de datos de la trama

Cálculo del CheckSum

Se pasan los bytes de datos pasados a la función codificando los bytes necesarios según el protocolo de comunicaciones

Se da valor al byte de final de trama

Activación del bit del registro de estado que indica transmisión de frame activa.

Envío del 1er byte de trama mediante la llamada a la función ComByteTx 0/1 ()

Contador de Bytes enviados = 1

Se retorna 1 indicando que la petición de envío de trama ha sido aceptada.

Page 32: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

32

Diagrama de flujo de la función ‘ComAttUartRx 0/1 ( )’ En la figura 6 se muestra el diagrama de flujo de la función ConAttUartRx0/1 ().

Figura 6. Diagrama de flujo de la función ConAttUartRx0/1()

No se guarda el byte, pero activa un indicador que informa que el siguiente byte que se reciba habrá que decodificarlo

Señaliz de recepción de trama activa

Byte indicador de codificación El primero

Si se ha reiniciad otra trama después de un intento anterior fallido se desmarca el error anterior.

Final trama Byte normal

Se guarda en el buffer de recepción del puerto Com seleccionado.

Ya se ha recibido la trama entera. Se pasa ha las comprobar la corrección de ésta.

¿Correcto?

¿Correcto?

Comprobación del número de bytes de datos de la trama

Comprobación del CheckSum Activación del error de trama

No

No

¿Qué byte se está recibiendo?

Indicación de recepción de la trama correcta y desmarcación de recepción de trama activa.

Llamamiento a la función funApp0/1( )

Se decodifica y se guarda.

Byte indicador de codificación

Se espera a una nueva interrupción de recepción

Interrupción de recepción

Page 33: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

33

4.3.2. Segunda Capa: Capa de Abstracción del Controlador de Display.

Esquema de llamadas entre funciones de la segunda capa. En la figura 7 se muestra un esquema de las diferentes llamadas que se efectúan

entre las funciones de la segunda capa.

Figura 7. Esquema de llamadas entre las funciones de la segunda capa.

EpsonCfg( )

halInitRegisters( ) halInitLUT ( ) halClearVmem ( )

halReadReg8 ( )

halReadReg16 ( )

halReadReg32 ( )

halWriteReg8 ( )

halWriteReg16 ( )

halWriteReg32( )

halReadDisplay8 ( )

halReadDisplay16 ( )

halReadDisplay32 ( )

halWriteDisplay8 ( )

halWriteDisplay16 ( )

halWriteDisplay32( )

Page 34: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

34

Diagrama de flujo de la función ‘EpsonCfg ( )’. En la figura 8 se muestra el diagrama de flujo de la función EpsonCfg().

Figura 8. Diagrama de flujo de la función EpsonCfg()

Se da valor a los punteros de comienzo de espacio de registros y comienzo de memoria de display

Se ajustan de los parámetros, velocidad y "wait states" del bus entre el microcontrolador y el S1D13A05

Se fuerza el reset del S1D13A05

Llamada a la función halInitRegisters( )

Llamada a la función halInitLUT ( )

Llamada a la función halClearVmem ( )

Page 35: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

35

4.3.3. Tercera Capa: Librería Gráfica.

Esquema de llamadas entre funciones de la tercera capa. En la figura 9 se muestra un esquema de las diferentes llamadas que se efectúan

desde la función SetRectangulo().

Figura 9. Esquema de llamadas a función desde SetRectangulo().

En la figura 10 se muestra un esquema de las diferentes llamadas que se efectúan

desde las funciones WrDispText() y SetBmp().

Figura 10. Esquema de llamadas a función desde SetBmp() y WrDispText().

SetRectangulo( )

SetLine( ) _Swap( )

SetPixel ( )

_SwapWord ( )

_Pixel4bpp ( ) _Pixel8bpp ( ) _Pixel16bpp( ) _Pixel2bpp ( ) _Pixel1bpp ( )

WrDispText( ) SetBmp ( )

_SwapWord ( )

_SwapDWord( )

_DivConRedSup( )

_MultiploDe4( )

GetColor ( )

SetColor ( )

GetBckColor ( )

SetBckColor ( )

Page 36: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

36

En la figura 11 se muestran las diferentes llamadas a función que se realizan para ejecutar las funciones RedimensionWindow(), MoveWindow (), MinWindow (), MaxWindow (), MoveUpText () y AddText ().

Figura 11. Esquema de llamadas a función desde las funciones de ventana.

SetWindowActive( )

DrawFrame ( ) SetRectangulo( ) ShowFullWindowText ( )

SetBmp( ) SetLine( ) SetPixel ( )

RedimensionWindow( ) MoveWindow ( ) MinWindow ( ) MaxWindow ( ) MoveUpText ( ) AddText ( )

_Pixel1bpp ( ) _Pixel4bpp ( ) _Pixel8bpp ( ) _Pixel2bpp ( ) _Pixel16bpp( )

Page 37: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

37

Diagrama de flujo de la función ‘ShowFullWindowText ( )’ En las figura 12 y figura 13 se muestra el diagrama de flujo de la función

ShowFullWindowText ().

Figura 12. Diagrama de flujo de la función ShowFullWindowText () 1/2.

Cálculo de parámetros: - Píxels por línea - Caracteres por línea - Número de líneas de texto - Número de líneas de ventana

Acotación del desplazamiento máximo del texto

Cálculo de la línea de texto desde donde se empezará a escribir

¿Hay imagen de fondo para

insertar?

Cálculo de su ubicación

Inserción de la imagen

Cálculo del índice del primer carácter

¿Se ha de empezar a escribir el texto desde el

principio?

Corresponde a las situaciones en que sea la primera vez que se escribe en la ventana o que todo

el texto quepa en la ventana

No Sí

Page 38: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

38

Figura 13. Diagrama de flujo de la función ShowFullWindowText () 2/2.

Como ya se sabe lo que cabe en la ventana se puede calcular cual es el último carácter a escribir

El final de escritura vendrá marcado por el carácter NULL

Sólo se escribe el texto que cabe en la ventana, que es el que interesa visualizar. Para eso se han hecho los cálculos anteriores

¿Ha llegado la escritura al final de la ventana o

al carácter NULL?

Se empieza a reescribir desde el principio de la ventana pero esta vez a partir de una línea de texto más que la vez anterior

Final ventana Carácter

NULL

Se ha acabado la escritura

Se dibuja el marcador de altura de visualización de texto

No Sí

Page 39: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

39

Diagrama de flujo de la función ‘SetBmp ( )’ En la figura 14 y la figura 15 se muestra el diagrama de flujo de la función

SetBmp().

Figura 14. Diagrama de flujo de la función SetBmp () 1/2.

El dibujo de imágenes se ejecuta en words con el objetivo de aprovechar al máximo

el ancho de bus. El problema que acarrea esta optimización de velocidad es que los words de display sólo pueden ser direccionados con direcciones naturales, lo que correspondería en el caso de 4bpp por ejemplo a índices de píxel dentro de una línea de 0, 4, 8, etc. Siendo por lo explicado imposible direccionar un word a partir de un píxel con índice no múltiplo de 4. Sin embargo es posible que se quiera dibujar una imagen a partir del píxel 3. Esto se considera, a modo de explicación, un desplazamiento de la imagen.

Extracción de las características de la imagen:

- Ancho de imagen en píxels - Alto de imagen en píxels - Bits por píxel

El ancho de imagen se calcula en bytes y words

¿Bpp de la imagen?

En el caso de 16bpp es un simple volcado de los words ya que no hay ningún posible desplazamiento. Esto evita el tener que preparar y aplicar máscaras, así como preparar los words de la imagen antes de hacer la OR con el word de display

1bpp 2bpp 4bpp 8bpp 16bpp

Los casos de 1, 2, 4 y 8 bpp son conceptualmente iguales por lo que lo explicado será válido para los 4 casos

Preparación de las máscaras para el primer, penúltimo y último word. Esta máscara es en función de la posición de la imagen en pantalla.

Continua en la hoja siguiente

Page 40: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

40

Figura 15. Diagrama de flujo de la función SetBmp () 2/2.

1er Word: - Cálculo de la dirección del word de display a modificar - Aplicación de la máscara al word de display, los bits a modificar

deben quedar a cero y el resto inalterados. - Preparación del primer word de la imagen, si la imagen está

desplazada se pasará sólo el trozo del word que corresponda y en la posición adecuada. El sobrante del word de la imagen debe estar a cero.

- El word de display será el resultado de la OR entre el word de display (después de la aplicación anterior de la máscara) y el word de la imagen preparado.

Words intermedios: Bucle de n iteraciones - Cálculo de la dirección del word de display a

modificar. - Preparación del word correspondiente de la

imagen, se sigue arrastrando el desplazamiento anterior de la imagen.

- Volcado del contenido del word de la imagen preparado al word de display correspondiente

Penúltimo Word: - Cálculo de la dirección del word de display a modificar - Aplicación de la máscara al word de display - Preparación del word correspondiente de la imagen, se sigue

arrastrando el desplazamiento inicial. - El word de display será el resultado de la OR entre el word de

display (después de la aplicación anterior de la máscara) y el word de la imagen preparado.

Último Word : - Se realiza exactamente igual que el penúltimo. - Se realizan por separado el penúltimo y último word porque no se

sabe en un primer momento el número de words de display que ocupará la imagen en pantalla debido al posible desplazamiento de ésta.

Bucle para dibujar las líneas de la imagen. Nº iteraciones = alto imagen

Page 41: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

41

Diagrama de flujo de la función ‘SetRectangulo ( )’ En la figura 16 y figura 17 se muestra el diagrama de flujo de la función

SetRectangulo().

Figura 16. Diagrama de flujo de la función SetRectangulo() 1/2.

El dibujo de rectángulos se ejecuta en words con el objetivo de aprovechar al

máximo el ancho de bus. El problema que acarrea esta optimización de velocidad es que los words de display sólo pueden ser direccionados con direcciones naturales, lo que correspondería en el caso de 4bpp por ejemplo a índices de píxel dentro de una línea de 0, 4, 8, etc. Siendo imposible direccionar un word a partir de un píxel con índice no múltiplo de 4. Sin embargo es posible que se quiera dibujar una imagen a partir del píxel 3. Esto se considera, a modo de explicación, un desplazamiento del rectángulo.

Cálculo de las dimensiones del rectángulo: - Ancho de rectángulo en píxeles - Alto de rectángulo en píxeles

El ancho y alto del rectángulo se calculan en words

¿Bpp del rectángulo?

En el caso de 16bpp es un simple volcado de los words ya que no hay ningún posible desplazamiento. Esto evita el tener que preparar y aplicar máscaras, así como preparar los primeros, últimos y penúltimos words de cada línea del rectángulo antes de hacer la OR con el word de display

1bpp 2bpp 4bpp 8bpp 16bpp

Los casos de 1, 2, 4 y 8 bpp son conceptualmente iguales por lo que lo explicado será válido para los 4 casos

Preparación de las máscaras para el primer, penúltimo y último words. Esta máscara es en función de la posición del rectángulo en pantalla.

Continua en la hoja siguiente

Page 42: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

42

Figura 17. Diagrama de flujo de la función SetRectangulo() 2/2.

1er Word: - Cálculo de la dirección del word de display a modificar - Aplicación de la máscara al word de display, los bits a modificar

deben quedar a cero y el resto inalterados. - Preparación del primer word del rectángulo, si este está desplazado se

pasará sólo el trozo del word que corresponda, y en la posición adecuada. El sobrante del word debe estar a cero.

- El word de display será el resultado de la OR entre el word de display (después de la aplicación anterior de la máscara) y el word del rectángulo preparado.

Words intermedios: Bucle de n iteraciones - Cálculo de la dirección del word de display a

modificar. - Volcado del contenido del word del rectángulo

preparado al word de display correspondiente

Penúltimo Word: - Cálculo de la dirección del word de display a modificar - Aplicación de la máscara al word de display - Preparación del word correspondiente del rectángulo, se sigue

arrastrando el desplazamiento inicial. - El word de display será el resultado de la OR entre el word de display

(después de la aplicación anterior de la máscara) y el word del rectángulo preparado.

Último Word : - Se realiza exactamente igual que el penúltimo. - Se realizan por separado el penúltimo y último word porque no se

sabe en un primer momento el número de words de display que ocupará el rectángulo en pantalla debido al posible desplazamiento de éste.

Bucle para dibujar las líneas del rectángulo. Nº iteraciones = altura rectángulo en píxeles

Page 43: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

43

4.4. Creación de las Fuentes de Letra Independientemente al software desarrollado para el sistema existe un trabajo que consiste en la creación de las fuentes de letra usadas en el sistema. El trabajo de creación de las fuentes ha sido desarrollado en Visual C.

Cada juego de fuentes de letra ha sido extraído a partir de la información de una imagen en formato BMP (mapa de bits) que contenía los caracteres deseados. Las imágenes que contienen los caracteres ASCII han sido creadas con la aplicación Paint de Microsoft. La figura 18 muestra una de las imágenes usadas para la creación de las fuentes de letra, la imagen ha sido particionada en dos líneas para poder ser visualizada:

Figura 18. Imagen con la fuente Lucida Console, tamaño 10.

Para los juegos de fuentes de letra se ha usado un tipo de fuente con tamaño de letra

constante. Los juegos de letra que actualmente se han incorporado al sistema son los tamaños 8, 10 y 12 de ‘Lucida Console’. Pudiendo incorporar nuevos tipos o tamaños de letra sin ningún tipo de problema gracias al software desarrollado, exceptuando fuentes con tamaños por encima del máximo permitido del cual se hablará más adelante. El hecho de tener el tamaño de carácter fijo facilita la cuenta de caracteres dentro de una ventana de texto, y todas las operaciones que derivan de su cuenta, que son muchas.

Las imágenes de fuentes de letra son como ya se ha comentado anteriormente mapas de bits, la profundidad de color es de un bit por píxel, por lo que una letra de diez píxeles de ancho y 16 de alto por ejemplo ocupará en principio un tamaño de memoria de 10x16bits. Para más información sobre los mapas de bits consultar el apartado ‘Anexo I. Información sobre Ficheros BMP’

Para estandarizar la posterior lectura de las fuentes de letra y realizar un proceso de lectura común para todos los tamaños y tipos de fuente se ha optado por representar la información de un carácter en tantos words como alta sea la fuente de letra. Cada word representa una línea del carácter, y se introducen en él todos los bits que contienen información sobre su línea de carácter, sobrarán bits dentro los words excepto en el caso de tamaño de letra de 16, pero gracias a esto se logra estandarizar la lectura de todas las fuentes de letra. Es fácil suponer que como máximo se podrán llegar a usar fuentes de letra con un ancho de carácter de 16. Esta limitación no supone ningún inconveniente ya que para el tipo de sistema que se está tratando no se deberían emplear fuentes de mayor tamaño orientadas a la escritura. Si se emplearan sería tal vez para algún título o dibujo, en tal caso bastaría con introducir los caracteres a usar como mapas de bits directamente.

El proceso de transformación de la imagen al array de words que contiene la información de cada una de las líneas de carácter de los caracteres ASCII consiste en los siguientes pasos:

Como ya se ha comentado, se ha de realizar un volcado de todos los bits que contienen la información de una línea de un carácter en un word. Se ha de tener en cuenta que un word de la imagen, de la imagen de partida creada con el Paint, puede contener información de uno, dos o tres caracteres; y que a su vez la información de un carácter puede estar comprendida en dos words diferentes. Por tanto se tendrá que realizar una reconstrucción de la información de la imagen para separarla en words que contengan únicamente información de la línea de un carácter.

Page 44: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

44

Como resultado del proceso anterior se obtiene un array de words que contiene únicamente información de la línea de un carácter. El inconveniente que tiene este array es que está desordenado; ya que lo que se busca es que el primer word sea la información de la primera línea del primer carácter, el segundo word sea la segunda línea del primer carácter y así sucesivamente. Sin embargo lo que se tiene en este momento es que el primer word sí que es la información de la primera línea del primer carácter pero el segundo es la primera línea del segundo carácter. Dicho de otro modo primero va la información de la primera línea de todos los caracteres, después de la segunda línea de todos los caracteres y así hasta la última línea del último carácter.

Por supuesto el último paso para la transformación de la imagen al array de words que se busca es la reordenación del array obtenido anteriormente.

El proceso de reordenación del array obtenido anteriormente es común para todos los tamaños y tipos de letra, cambiando una serie de valores por supuesto. Sin embargo el proceso anterior de reconstrucción de la información de la imagen para separarla en words que contengan únicamente información de la línea de un carácter es específico para cada tamaño de letra.

Una vez que se ha transformado la imagen al array buscado este es plasmado en un archivo de texto que se incorporará posteriormente como librería en el proyecto.

Page 45: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

45

5. Programación Después de explicar en el apartado ‘4. Resolución del Proyecto’ la filosofía de las

tres capas software de las que se compone este proyecto se procede a explicar en detalle cada una de las funciones de las que se componen.

Para obtener una previa visión global de todas las funciones se aconseja mirar en primer lugar el subapartado ‘4.3. Conexiones entre Funciones y Diagramas de Flujo’ para observar la jerarquía, dependencia y relaciones entre las diferentes funciones que componen cada estrato del software.

En cuanto a la explicación de las funciones se sigue el siguiente la siguiente estructura:

• Objetivo de la función: explica la misión de ésta sin entrar en detalles de estructura interna.

• Parámetros de entrada: enumera los parámetros de entrada que posee la función describiendo a su vez cada uno de ellos.

• Estructura de la función: sin llegar a entrar en el nombramiento de instrucciones se explica como se plantea internamente la función para la consecución de los objetivos previamente mencionados.

• Retorno de la función: si la función retorna algún parámetro a su finalización éste se menciona y se explica.

Page 46: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

46

5.1. Funciones de la Primera Capa int TimSet (int numTimer, int ms, int mode, void (*timer_func)() ); Objetivo: Configurar el timer seleccionado, incluyendo el modo de funcionamiento, el período y la función a llamar por la interrupción del timer. Parámetros de entada:

- numTimer: Selecciona el timer a configurar. - ms: Periodo del timer en milisegundos. - *timer_func(): Puntero a la función que se quiere asociar a la interrupción del

timer seleccionado. Estructura de la función: Asigna el puntero a función pasado como parámetro de entrada al puntero global que es llamado a cada salto de interrupción del timer. Da valor a los registros asociados al timer para ajustar el periodo y el modo de funcionamiento del timer. Retorna:

Cero o uno según sean válidos o no los parámetros de configuración. void TimStop (int numTimer); Objetivo: Parar la cuenta del timer seleccionado. Parámetros de entada:

- numTimer: Selecciona el timer a parar. Estructura de la función: Modifica el registro asociado al timer seleccionado para detener su funcionamiento. void TimStart (int numTimer); Objetivo: Activar el timer seleccionado. Parámetros de entada:

- numTimer: Selecciona el timer a activar. Estructura de la función: Deshabilita el timer seleccionado, inicializa su cuenta, lo rehabilita y comienza la cuenta de éste. void LedpinsCfg(void); Objetivo: Configurar los pines asociados a los leds. Estructura de la función: Configura los pines asociados a los leds como pines de propósito general de entrada/salida. A continuación los define como salidas. void LedOn(unsigned int NumLed); Objetivo: Enciende el led o los leds seleccionados. Parámetros de entada:

- NumLed: Selecciona el led o los leds a encender. Los leds pueden ir del 0 al 5 o varios a la vez.

Estructura de la función:

Page 47: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

47

Enciende el led o los leds seleccionados modificando el registro de estado de los pines de propósito general. void LedOff(unsigned int NumLed); Objetivo: Apagar el led o los leds seleccionados. Parámetros de entada:

- NumLed: Selecciona el led a apagar. Los leds pueden ir del 0 al 5 o varios a la vez. Estructura de la función: Apaga el led o los leds seleccionados modificando el registro de estado de los pines de propósito general. void LPC2294SystemInit(void); Objetivo:

Configurar los pines y parámetros del microcontrolador para su correcto funcionamiento dentro del sistema. Se tiene en cuenta en este apartado la configuración de pines para comunicación con memorias RAM, Flash y el debugger, modelo IAR L-Link-KS JTAG, así como la configuración de sus respectivos buses. Estructura de la función: Selecciona la memoria a la que se mapearán los vectores de interrupción. Configura los pines y parámetros para el funcionamiento del microcontrolador dentro de la placa implementada. int PllSetup(int xtal_mhz, int cclk_mhz); Objetivo: Configurar el PLL del microcontrolador para obtener la frecuencia seleccionada. Parámetros de entada:

- Xtal_mhz: Frecuencia en MHz del cristal oscilador implementado a la entrada del microcontrolador.

- Cclk_mhz: Frecuencia en MHz deseada. Estructura de la función: Se calculan los parámetros necesarios para el ajuste del PLL a partir de la relación entre las frecuencias pasadas a la función. Se deshabilitan las interrupciones, se ajustan los registros asociados al PLL, se espera a que se sincronice y se vuelven a habilitar las interrupciones. int ComCfg ( int port, int velocitat, int bits, int bitstop, int parity,

void(*uart_rx_func)(void), void(*uart_tx_func)(void) ); Objetivo: Configurar el puerto seleccionado según los parámetros de entrada pasados. Parámetros de entada:

- port: Puerto a configurar. - Velocitat: Velocidad del puerto en bits por segundo. - Bitstop: Número de bits de stop. - Parity: Tipo de paridad. - *uart_rx_fun(): Puntero a la función que se desea llamar cuando salte la

interrupción de buffer de recepción lleno del puerto seleccionado. - *uart_tx_fun(): Puntero a la función que se desea llamar cuando salte la

interrupción de buffer transmisión vacío del puerto seleccionado. Estructura de la función:

Page 48: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

48

Ajusta los registros asociados al puerto seleccionado para configurarlo según los parámetros de entrada pasados a la función. Asigna el valor de los punteros de las funciones que se desea que sean llamados por las interrupciones a los punteros globales que son llamados en caso de salto de interrupción. Retorna:

Cero o uno según sean válidos o no los parámetros de configuración. int ComClose (int port); Objetivo: Cerrar el puerto seleccionado. Parámetros de entada:

- port: Puerto a cerrar. Estructura de la función: Configura los registros asociados al puerto seleccionado para que éste quede cerrado y no pueda recibir ni enviar datos. Las interrupciones de envío y recepción quedan deshabilitadas. Retorna:

Cero o uno según sean válidos o no los parámetros de entrada.

int ComOpen (int port); Objetivo: Abrir el puerto seleccionado. Parámetros de entada:

- port: Puerto a abrir. Estructura de la función: Configura los registros asociados al puerto seleccionado para que éste quede abierto y pueda recibir y enviar datos. La interrupción de recepción queda habilitada. Retorna:

Cero o uno según sean válidos o no los parámetros de entrada. int ComFrmTx (int port, unsigned char *tx, int NumBytes); Objetivo: Enviar la trama de datos pasada como parámetro de entrada mediante el puerto Com seleccionado siguiendo el protocolo de comunicaciones del sistema. La explicación del protocolo se puede encontrar en el apartado ‘2.5. Descripción del Protocolo de Comunicaciones’. Parámetros de entada:

- port: Puerto seleccionado. - *tx: Trama de datos a enviar por el puerto Com seleccionado. - NumBytes: Número de bytes que contiene la trama de datos a enviar.

Estructura de la función: Primero comprueba, consultando el registro de estado del puerto Com seleccionado, que no haya ningún envío de trama anterior activo, si es el caso no empieza una la transmisión de trama hasta que no se acabe la anterior, retornando la función con un cero para indicar que el envío no ha sido efectuado con éxito. A continuación se construye la trama a enviar en el buffer de trama de envío perteneciente a la propia función y por supuesto correspondiente al puerto Com seleccionado:

• Se da valor al byte de comienzo de trama.

Page 49: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

49

• Se da valor al byte que indica el número de bytes de datos que contiene la trama según el parámetro de entrada introducido.

• Se calcula el valor del campo CheckSum, cogiendo únicamente el byte de menor peso.

• Se introducen los bytes de datos pasados a la función en el campo de datos de la trama a enviar, codificando los bytes que sean necesarios según las normas del protocolo de comunicaciones.

• Por último se da valor al byte de final de trama. Se activa el bit que indica transmisión de frame activa del registro de estado del

puerto Com seleccionado. Este bit se mantendrá a uno hasta que finalice el envío de la trama.

Se inicia la transmisión de la trama enviando manualmente el primer byte de ésta mediante la función ComByteTx(). El resto de bytes serán enviados así como se vaya vaciando el buffer de transmisión mediante el salto de la interrupción de buffer vacío correspondiente al puerto Com seleccionado. La función que se encarga de atender el salto de la interrupción es ComAttUartTx0/1() del puerto Com que está enviando la trama. Una vez se ha enviado el primer byte de la trama se pone a uno el contador global de bytes de trama enviados.

Por último se retorna uno indicando que la petición de envío de trama ha sido aceptada. Retorna:

Uno si la petición de envío de trama ha sido aceptada, cero si no ha sido aceptada debido a la existencia de un envío anterior activo. int ComRdRx (int port, unsigned char *Rx); Objetivo: Coger la trama recibida por ComAttUartRx0/1(), según el puerto seleccionado, y de ella obtener tan sólo los bytes de datos para volcarlos al buffer indicado como parámetro de entrada.

Devolver el número de bytes de datos que contiene la trama recibida. Parámetros de entada:

- port: Puerto seleccionado. - *Rx: Puntero al buffer donde se quiere volcar los bytes de datos de la trama

recibida por el puerto seleccionado. Estructura de la función: Vuelca los bytes de datos de la trama recibida por el puerto seleccionado al buffer que se ha seleccionado como parámetro de entrada. Pone a cero el bit de recepción de trama correcta del registro de estado del puerto Com tratado para indicar que los datos recibidos ya han sido almacenados y que por tanto se puede comenzar otra recepción. Por último retorna el número de bytes de datos que contenía la trama recibida. Retorna:

El número de bytes de datos que contenía la trama recibida. int ComRxApp ( int port, void(*funApp)() ); Objetivo: Asignar la función seleccionada en los parámetros de entrada a un puntero global que es llamado una vez se ha finalizado la recepción de una trama. Parámetros de entada:

- port: Puerto seleccionado. - *funApp(): Puntero a la función que se quiere asignar al puntero global.

Page 50: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

50

Estructura de la función: Se asigna la función pasada como parámetro de entrada al puntero global que es llamado por ComAttRx() cada vez que se finaliza la recepción de una trama. La función que sea asignada al puntero global será la que se encargue del almacenamiento de los datos de la trama recibida por el puerto Com seleccionado. Retorna:

Cero o uno según sean válidos o no los parámetros de entrada pasados. char ComGetSt (int port); Objetivo: Consultar el estado del puerto Com seleccionado. Parámetros de entada:

- port: Puerto seleccionado. Estructura de la función: Retorna el registro de estado correspondiente al puerto Com seleccionado. Retorna: Retorna el registro de estado correspondiente al puerto Com seleccionado. void ComAttUartTx0 (void); Objetivo:

Cargar en el registro de envío el siguiente byte a transmitir de la trama que está siendo enviada. Esta función es la llamada por la interrupción de buffer de transmisión vacío del puerto Com0. Estructura de la función:

Esta función es llamada cuando una vez ha saltado la interrupción del puerto Com0 se constata que la fuente de interrupción ha sido la interrupción de transmisión.

Carga en el registro de envío el siguiente byte a transmitir de la trama que está siendo enviada, esto se realiza con un llamamiento a la función ComByteTx0().

Comprueba que ya no queden más bytes por enviar, si es el caso desactiva la interrupción de transmisión (interrupción de buffer de transmisión vacío) y modifica el registro de estado del Com0, desactivando el bit de transmisión de frame activa.

void ComAttUartRx0 (void); Objetivo:

Realizar la recepción de las tramas enviadas al puerto Com0. En la recepción se incluye la descodificación de los bytes que lo requieran, la comprobación del valor del CheckSum y la indicación de trama correcta o incorrecta. Estructura de la función: Se recepciona el primer byte de la trama y se modifica el registro de estado para indicar que existe una recepción de trama activa. Si se ha recomenzado otra trama después de un intento anterior fallido se desmarca el error anterior. En la recepción de los siguientes bytes se comprueba si están codificados, o si es el byte de final de trama. Si no fuese ningún caso anterior es que es un byte normal por lo que se guarda en el buffer de recepción. Si se está ante un byte indicador de codificación éste no se guarda pero activa un indicador que informa que el siguiente byte que se reciba estará codificado por lo que habrá que descodificarlo antes de guardarlo. Cuando se recepciona el byte de final de trama se comprueba el número de bytes de datos, si hay una incorrección se activa el error de trama, en caso contrario se pasa a la

Page 51: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

51

comprobación del CheckSum. Para ello se calcula el CheckSum de la trama recibida y se compara con el CheckSum recibido. Si es incorrecto se activa el error de trama, si es correcto se modifica el registro de estado de comunicaciones para indicar la correcta recepción de la trama y desmarcar el la recepción de trama activa.

Por último, siguiendo en la hipótesis de una correcta recepción, se hace un llamamiento a la función funApp0 ( ), siempre que el usuario la haya asignado como función a llamar después de la recepción de una trama. void ComAttUartTx1 (void); Objetivo:

Cargar en el registro de envío el siguiente byte a transmitir de la trama que está siendo enviada. Esta función es la llamada por la interrupción de buffer de transmisión vacío del puerto Com1.

Estructura de la función:

Esta función es llamada cuando una vez ha saltado la interrupción del puerto Com1 se constata que la fuente de interrupción ha sido la interrupción de transmisión.

Carga en el registro de envío el siguiente byte a transmitir de la trama que está siendo enviada, esto se realiza con un llamamiento a la función ComByteTx1().

Comprueba que ya no queden más bytes por enviar, si es el caso desactiva la interrupción de transmisión (interrupción de buffer de transmisión vacío) y modifica el registro de estado del Com1, desactivando el bit de transmisión de frame activa.

void ComAttUartRx1 (void); Objetivo:

Realizar la recepción de las tramas enviadas al puerto Com1. En la recepción se incluye la descodificación los bytes que lo requieran, la comprobación del valor del CheckSum y la indicación de trama correcta o incorrecta. Estructura de la función: Se recepciona el primer byte de la trama y se modifica el registro de estado para indicar que existe una recepción de trama activa. Si se ha recomenzado otra trama después de un intento anterior fallido se desmarca el error anterior. En la recepción de los siguientes bytes se comprueba si están codificados, o si es el byte de final de trama. Si no fuese ningún caso anterior es que es un byte normal y se guarda en el buffer de recepción. Si se está ante un byte indicador de codificación éste no se guarda pero activa un indicador que informa que el siguiente byte que se reciba estará codificado por lo que habrá que descodificarlo antes de guardarlo. Cuando se recepciona el byte de final de trama se comprueba el número de bytes de datos, si hay una incorrección se activa el error de trama, en caso contrario se pasa a la comprobación del CheckSum. Para ello se calcula el CheckSum de la trama recibida y se compara con el CheckSum recibido. Si es incorrecto se activa el error de trama, si es correcto se modifica el registro de estado de comunicaciones para indicar la correcta recepción de la trama y desmarcar el la recepción de trama activa.

Por último, siguiendo en la hipótesis de una correcta recepción, se hace un llamamiento a la función funApp1 ( ), siempre que el usuario la haya asignado como función a llamar después de la recepción de una trama.

Page 52: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

52

void ComByteTx0 (unsigned char byte); Objetivo: Cargar el registro de envío del puerto Com0 con el valor pasado como parámetro de entrada. Parámetros de entada:

- byte: Char que se quiere enviar por el puerto Com0. Estructura de la función: Carga el valor que queremos enviar en el registro de envío del puerto Com0 dentro de un bucle del cual sale una vez se ha comprobado que el registro de envío del puerto ha sido cargado. void ComByteTx1 (unsigned char byte); Objetivo: Cargar el registro de envío del puerto Com1 con el valor pasado como parámetro de entrada. Parámetros de entada:

- byte: Char que se quiere enviar por el puerto Com1. Estructura de la función: Carga el valor que queremos enviar en el registro de envío del puerto Com1 dentro de un bucle del cual sale una vez se ha comprobado que el registro de envío del puerto ha sido cargado. int VectSet (int numVec, void (*func)()); Objetivo: Habilitar la interrupción del vector de interrupción seleccionado y asociar la función pasada al vector. Parámetros de entada:

- numVec: Número de vector de interrupción. - *fun.(): Puntero a la función que se quiere asociar al vector de interrupción

seleccionado. Estructura de la función: Habilita la interrupción del vector de interrupción seleccionado y asocia la función pasada al vector. Retorna:

Cero o uno según sean válidos o no los parámetros de entrada. int VectRst (int numVec); Objetivo: Resetear el vector de interrupciones seleccionado. Parámetros de entada:

- numVec: Número de vector de interrupción a resetear. Estructura de la función: Deshabilita el vector de interrupción seleccionado como parámetro de entrada. Retorna:

Cero o uno según sean válidos o no los parámetros de entrada. int VectGet (int numVec, void (**fun)()); Objetivo: Obtener el puntero de la función apuntada por el vector de interrupciones seleccionado.

Page 53: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

53

Parámetros de entada: - numVec: Número de vector de interrupción. - **fun(): Dirección de puntero donde se pretende copiar el puntero señalado por el

vector de interrupciones seleccionado. Estructura de la función: Carga el valor del puntero del vector de interrupciones seleccionado en la dirección de puntero pasada como parámetro de entrada. Retorna:

Cero o uno según sean válidos o no los parámetros de entrada. void AttInt_UART0 (void); Objetivo: Su principal función es averiguar la fuente de la interrupción y llamar a la función oportuna.

Es la función llamada por el vector de interrupción del puerto 0. Estructura de la función: Lo primero que hace es averiguar quien ha hecho saltar la interrupción. Según la fuente que sea se llamará a la función que señala el puntero asociado a la fuente de causante de la interrupción. Los punteros asociados a las fuentes de interrupción son globales, la asignación de la función apropiada al puntero se realiza en otras funciones. void AttInt_UART1 (void); Objetivo: Su principal función es averiguar la fuente de la interrupción y llamar a la función oportuna.

Es la función llamada por el vector de interrupción del puerto 1. Estructura de la función: Lo primero que hace es averiguar quien ha hecho saltar la interrupción. Según la fuente que sea se llamará a la función que señala el puntero asociado a la fuente de causante de la interrupción. Los punteros asociados a las fuentes de interrupción son globales, la asignación de la función apropiada al puntero se realiza en otras funciones. void AttInt_Timer0 (void); Objetivo:

Es la función llamada por el vector de interrupción del timer 0. Se encarga de llamar a la función asignada a la interrupción del timer 0. Sólo hay una función asignada a las interrupciones del timer 0 independientemente de la naturaleza de la interrupción. Estructura de la función:

Llama a la función que señala el puntero asociado a la interrupción del timer 0. El puntero asociado a la interrupción del timer 0 es global, la asignación de la función apropiada al puntero se realiza en otra función.

void AttInt_Timer1 (void); Objetivo:

Es la función llamada por el vector de interrupción del timer 1. Se encarga de llamar a la función asignada a la interrupción del timer 1. Sólo hay una función asignada a las interrupciones del timer 1 independientemente de la naturaleza de la interrupción. Estructura de la función:

Page 54: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

54

Llama a la función que señala el puntero asociado a la interrupción del timer 1. El puntero asociado a la interrupción del timer 1 es global, la asignación de la función apropiada al puntero se realiza en otra función. void funApp0 (void); Objetivo: Hacer uso de los bytes del campo de datos de la trama recibida por el puerto Com0 al que está asociada. Estructura de la función: Esta función previamente tiene que haber sido asociada al puntero global que es llamado cada vez que se completa la recepción de una trama.

La función hará uso de los bytes de datos de la trama recibida. La funcionalidad implementada en estos momentos para esta función es volver a enviar lo que ha recibido con la única intención de confirmar el buen funcionamiento de las comunicaciones. Pero su verdadera intención es que el usuario implemente lo necesario para el uso que necesite realizar de los datos recibidos. void funApp1 (void); Objetivo: Hacer uso de los bytes del campo de datos de la trama recibida por el puerto Com1 al que está asociada. Estructura de la función: Esta función previamente tiene que haber sido asociada al puntero global que es llamado cada vez que se completa la recepción de una trama.

La función hará uso de los bytes de datos de la trama recibida. La funcionalidad implementada en estos momentos para esta función es volver a enviar lo que ha recibido con la única intención de confirmar el

buen funcionamiento de las comunicaciones. Pero su verdadera intención es que el usuario implemente lo necesario para el uso que necesite realizar de los datos recibidos.

Page 55: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

55

5.2. Funciones de la Segunda Capa int EpsonCfg ( UInt32 MemAddress, UInt32 RegAddress,int ColorType, int bits_per_pixel, UInt32 pixels_per_line,

UInt32 pixels_per_colum ); Objetivo:

Dar valor a los punteros globales que apuntan a las direcciones de comienzo de la memoria de display del S1D13A05 y de su espacio de registros.

Habilitar los pines del LPC2294 para la interacción con el Epson. Ajustar parámetros, velocidades y estados de espera del bus entre el LPC2294 y el

S1D13A05. Configurar los registros del Epson según los parámetros indicados. Inicializar la LUT con unos valores por defecto según los parámetros de entrada

pasados, aunque posteriormente también se pueden volver a ajustar. Resetear la memoria de display del Epson. Como objetivo general pretende ser una función de configuración totalmente

parametrizable que evite del acceso específico a todo registro de configuración del S1D13A05. Parámetros de entada:

- MemAddress: Posición de memoria donde comienza la memoria de display del S1D13A05.

- RegAddress: Posición de memoria donde comienza el espacio de registros del S1D13A05.

- ColorType: '0' Escala de grises, '1' Color. - bits_per_pixel: Bits por píxel. - pixels_per_line: Píxels por línea. - pixels_per_colum: Píxels por columna.

Estructura de la función: Se compone de una lectura referenciada a partir de la suma del puntero global que apunta al comienzo de la zona de memoria de display junto con el offset introducido como parámetro de la función. Retorna:

Cero o uno según sean válidos o no los valores de configuración. void halpClearVmem ( void ); Objetivo:

Poner a cero toda la memoria de display. Lo cual provoca que toda la pantalla se quede en negro. Estructura de la función:

Se compone de un bucle que recorre toda la memoria de display para poner a cero cada posición, partiendo del puntero global que indica la dirección de comienzo de esta zona de memoria. void halInitRegisters( int ColorType, int bits_per_pixel, UInt32

pixels_per_line, UInt32 pixels_per_colum ); Objetivo: Dar valor a todos los registros de configuración del Epson que se van a usar en esta aplicación en concreto. Más en concreto dar valor a los registros de ajuste de buses, tipo de panel, ajustes de display, modo bajo consumo, modos de display, pines de propósito general y pines de salida.

Page 56: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

56

Parámetros de entada: - ColorType: '0' Escala de grises, '1' Color. - bits_per_pixel: Bits por píxel. - pixels_per_line: Píxels por línea. - pixels_per_colum: Píxels por columna.

Estructura de la función: Se compone únicamente de lecturas y escrituras a registros, no tiene complejidad estructural. Su complejidad radica en la buena elección de los numerosos parámetros a configurar. void halInitLUT( int ColorType, int bits_per_pixel); Objetivo: Cargar una serie de valores predefinidos a la LUT según la configuración de bbp y de color o escala de grises que se definan en los parámetros de entrada. Parámetros de entada:

- ColorType: '0' Escala de grises, '1' Color. - bits_per_pixel: Bits por píxel.

Estructura de la función: La función posee una serie de arrays que contienen los valores predefinidos necesarios para todas las posibles configuraciones de LUT que se puedan efectuar. Para saber cual usar diferencia primero si se está pidiendo una pantalla a color o en escala de grises, para posteriormente fijarse en que profundidad de color ha sido seleccionada.

Una vez encontrado el array a utilizar, los valores son cargados dentro de un bucle, definido en iteraciones por el número de entradas de la LUT (diferente para cada tipo y profundidad de color) y usando para su escritura un registro específico para introducir valores en la LUT. UInt8 halReadDisplay8 ( UInt32 Offset ); UInt16 halReadDisplay16 ( UInt32 Offset ); UInt32 halReadDisplay32 ( UInt32 Offset ); Objetivo: Realizar la lectura de la memoria de display. Parámetros de entada:

- Offset: El valor del índice que tiene la posición que se desea leer respecto a la primera posición de la memoria de display.

Estructura de la función: Se compone de una lectura referenciada a partir de la suma del puntero global que apunta el comienzo de la zona de memoria de display junto con el offset introducido como parámetro de la función. Retorna:

El valor obtenido de la lectura. void halWriteDisplay8 ( UInt32 Offset, UInt8 Value, UInt32 Count ); void halWriteDisplay16 ( UInt32 Offset, UInt16 Value, UInt32 Count ); void halWriteDisplay32 ( UInt32 Offset, UInt32 Value, UInt32 Count ); Objetivo: Escribir en la memoria de display. Parámetros de entada:

- Offset: Valor del índice que tiene la posición en la que se desea escribir respecto a la primera posición de la memoria de display.

Page 57: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

57

- Value: Valor que se desea escribir, el tipo de dato ha de corresponder según la función que se esté usando.

- Count: Número de veces que se quiere repetir la operación de escritura con el valor especificado.

Estructura de la función: Se compone de una escritura a memoria, siendo la posición de memoria referenciada a partir de la suma del puntero global que apunta el comienzo de la zona de memoria de display junto con el offset introducido como parámetro de entrada de la función. A continuación se encuentra un bucle que repite la operación de escritura tantas veces como indique el valor de Count. En cada iteración de este bucle se escribe el mismo valor introducido en la posición de memoria de display inmediatamente superior a la anterior. UInt8 halReadReg8 ( UInt32 Offset); UInt16 halReadReg16 ( UInt32 Offset); UInt32 halReadReg32 ( UInt32 Offset); Objetivo: Realizar la lectura de registros del S1D13A05. Parámetros de entada:

- Offset: Valor del índice que tiene el registro que se desea leer respecto a la primera posición de la memoria de registros.

Estructura de la función: Se compone de una lectura de registro, siendo la posición de memoria referenciada a partir de la suma del puntero global que apunta el comienzo de la zona de registros junto con el offset introducido como parámetro de la función. Retorna:

El valor obtenido de la lectura. void halWriteReg8 ( UInt32 Offset, UInt8 Value ); void halWriteReg16 ( UInt32 Offset, UInt16 Value ); void halWriteReg32 ( UInt32 Offset, UInt32 Value ); Objetivo: Escribir en los registros del S1D13A05. Parámetros de entada:

- Offset: Valor del índice que tiene el registro en el que se desea escribir respecto a la primera posición de la memoria de registros.

- Value: Valor que se desea escribir, el tipo de dato ha de corresponder según el la función que se esté usando.

Estructura de la función: Se compone de una escritura a registro, siendo la posición de memoria referenciada a partir de la suma del puntero global que apunta el comienzo de la zona de registros junto con el offset introducido como parámetro de la función.

Page 58: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

58

5.3. Funciones de la Tercera Capa int CfgDisplay (UInt32 MemAddress, UInt32 RegAddress,int ColorType,

int bits_per_pixel, UInt32 pixels_per_line, UInt32 pixels_per_colum)

Objetivo: Llamar a la función de configuración del S1D13A05, EpsonCfg ( ). Configurar los registros del Epson según los parámetros indicados. Inicializar la LUT con unos valores por defecto según los parámetros de entrada

pasados, aunque posteriormente también se pueden volver a ajustar. Resetear la memoria de display del Epson. Dar valor a los punteros globales que apuntan a las direcciones de comienzo de la

memoria de display del S1D13A05 y de su espacio de registros. Crear la ventana de escritorio, que es la ventana que se tendrá por defecto en

pantalla al iniciar el sistema. Aunque las características del escritorio están predefinidas si lo desea el usuario se pueden reconfigurar a posteriori.

Preinicializar el resto de ventanas poniendo a cero las variables oportunas. Como objetivo general pretende ser una función de configuración totalmente

parametrizable tanto para el propio dispositivo como para el tipo de panel, que también se configura con registros internos del dispositivo. Evitando el acceso específico a todo registro de configuración del S1D13A05. Parámetros de entada:

- MemAddress: Posición de memoria donde comienza la memoria de display del S1D13A05.

- RegAddress: Posición de memoria donde comienza el espacio de registros del S1D13A05.

- ColorType: '0' Escala de grises, '1' Color. - bits_per_pixel: Bits por píxel. - pixels_per_line: Píxels por línea. - pixels_per_colum: Píxels por columna.

Estructura de la función: Primero da valor a todas las variables globales de la librería a partir de los parámetros de entrada de la función. A continuación llama a la función EpsonCfg() de la capa inferior para la configuración del dispositivo. Preinicializa todas las ventanas del sistema, aunque no hayan sido inicializadas, poniendo las variables necesarias a cero. Por último inicializa la ventana escritorio con una serie de valores predefinidos en el sistema, aunque tiene en cuenta el tamaño de pantalla introducido por el usuario, ya que el escritorio es una ventana a pantalla completa. Retorna:

Si la ventana escritorio ha sido creada con éxito la función retorna un uno, si por el contrario ha habido algún problema retorna un cero.

void SetColor (UInt16 NewColor); Objetivo: Cambiar el color de escritura en pantalla. Parámetros de entada:

- NewColor: Valor del nuevo color con el que se quiere escribir en pantalla. Para profundidades de color de 1, 2, 4 y 8 bits por píxel el color es un índice de la LUT. Para 16 bits por píxel el color está en formato RGB.

Page 59: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

59

Estructura de la función: Asigna el valor del parámetro de entrada a la variable global que define el color de escritura en pantalla del sistema. UInt16 GetColor (void) Objetivo: Consultar el color de escritura en pantalla. Estructura de la función: Consulta el valor de la variable global que define el color de escritura en pantalla del sistema y lo retorna. Retorna: El valor actual de escritura en pantalla. void SetBckColor (UInt16 NewBckColor); Objetivo: Cambiar el color de dibujo en pantalla. El dibujo en pantalla incluye el dibujo de rectángulos, líneas y píxels. Parámetros de entada:

- NewBckColor: Valor del nuevo color con el que se quiere dibujar en pantalla. Para profundidades de color de 1, 2, 4 y 8 bits por píxel el color es un índice de la LUT. Para 16 bits por píxel el color está en formato RGB.

Estructura de la función: Asigna el valor del parámetro de entrada a la variable global que define el color de dibujo en pantalla del sistema. UInt16 GetBckColor (void) Objetivo: Consultar el color de dibujo en pantalla. El dibujo en pantalla incluye el dibujo de rectángulos, líneas y píxels. Estructura de la función: Consulta el valor de la variable global que define el color de dibujo en pantalla del sistema y lo retorna. Retorna: El valor actual de dibujo en pantalla. void WrDispText (char *pText, unsigned x, unsigned y); Objetivo: Escribir el texto al que apunta el puntero a cadena de caracteres de entrada a partir de la coordenada especificada. Parámetros de entada:

- *pText: Puntero al comienzo de la cadena de caracteres a escribir en pantalla. - X: Coordenada horizontal en píxels de la posición de comienzo de escritura. - Y: Coordenada vertical en píxels de la posición de comienzo de escritura.

Estructura de la función: A partir del código ASCII de cada carácter se va volcando su correspondiente símbolo, según la fuente activa, en pantalla. A la hora del volcado del símbolo correspondiente al carácter a escribir, se dibujarán sólo los píxeles correspondientes a la letra, todo lo que forma parte del fondo de la letra no se dibujará por lo que será transparente al fondo. En cuanto a la letra en si, que sí se dibuja, se usa el color que esté activo en el momento de la llamada a la función.

Page 60: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

60

Cuando se detecta final de pantalla se cambia de línea y se sigue escribiendo, así hasta que se detecte el carácter NULL que indica el final de la cadena de texto a mostrar.

void SetBmp(char *fname, unsigned DstX, unsigned DstY); Objetivo: Dibujar en la pantalla a partir de las coordenadas pasadas el bitmap seleccionado. Parámetros de entada:

- DstX: Coordenada horizontal donde se situará la esquina superior izquierda de la imagen.

- DstY: Coordenada vertical donde se situará la esquina superior izquierda de la imagen.

Estructura de la función: Lo primero a aclarar para explicar la estructura de esta función es que si el contenido de la imagen se pasa a pantalla en forma de words es para aprovechar la totalidad del ancho de bus (16 bits) que une el microcontrolador con el controlador de display del sistema. El segundo punto a aclarar es que la imagen no tiene porqué dibujarse a partir de una coordenada horizontal que sea múltiplo del cociente de la división 16/ bits por píxel de la imagen. Lo que se traduce en que el primer word a modificar en el display no contendrá cien por cien información de la imagen, sino que lo hará tan solo parcialmente. Esto es debido al posible desplazamiento que puede tener la imagen respecto a la posición múltiplo de la división comentada. Este desplazamiento se arrastrará en cada uno de los words de la imagen a pasar al display. Todo esto lleva a la necesidad de preparar los words a pasar al display aplicando máscaras y rotaciones de bits para adecuar la imagen a las coordenadas introducidas. Explicados los dos puntos anteriores se pasa a una descripción secuencial de las acciones que se realizan en esta función. Primero se extraen las características necesarias de la imagen leyendo los bytes oportunos del archivo BMP. Estas características engloban: ancho de la imagen en píxeles, alto de la imagen en píxeles y bits por píxel de la imagen. Se trata de manera independiente cada profundidad de color con el objetivo de dar mayor velocidad y transparencia al código, aunque conceptualmente se sigan los mismos pasos. A continuación se explica el caso genérico. Se preparan las máscaras que posteriormente se aplicarán para el dibujo del primer, penúltimo y último word. Las máscaras se aplicarán sobre los words de la memoria de display, poniendo a cero los bits a modificar y a uno los que se quieren dejar inalterados.

Dentro de un bucle de tantas iteraciones como alta sea la imagen se escribe a cada iteración cada una de las líneas de la imagen. Cada línea se compone del primer word de línea, de los words intermedios, del penúltimo y del último. Para el dibujo del primer word de cada línea se siguen los siguientes puntos. Se calcula la dirección de memoria del word de display a modificar. Se aplica la máscara al word de display. Se prepara el primer word de la línea, aplicando el desplazamiento oportuno según la situación de la imagen, y dejando a cero los bits del word que no contienen información de la imagen. Finalmente se realiza una OR entre el word de la imagen y el word de display. Los words intermedios se tratan dentro de un bucle. Para dibujarlos se calcula la dirección de memoria del word de display a modificar. Se prepara el word de la imagen, se sigue arrastrando el posible desplazamiento de la imagen. Por último se vuelca el contenido del word de la imagen, esta vez seguro que será cien por cien contenido de la imagen, en el word de display. Un word intermedio de display en caso de desplazamiento

Page 61: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

61

de la imagen diferente de cero contendrá información de dos words de imagen originales, por eso mismo es necesaria la preparación del word de la imagen. Para el penúltimo word se calcula de nuevo la dirección del word de display a modificar. Se aplica la máscara calculada anteriormente. Se prepara el word de la imagen. Finalmente se realiza una OR entre el word de la imagen y el word del display.

El último word se ejecuta exactamente igual que el penúltimo pero con su máscara propia.

Comentar el caso especial de la profundidad de color de 16 bits por píxel. En este caso no existe desplazamiento posible. Esto se debe a que cada píxel es representado por un word entero por lo que el dibujo de imágenes con esta profundidad de color consiste en un simple volcado de los words de la imagen en los words de display. Evitando el tener que preparar y aplicar máscaras, así como preparar cada word de la imagen antes de hacer el volcado en el word del display. int SetFont (UInt16 *pBufferFont,UInt8 sizex,UInt8 sizey); Objetivo: Configurar la fuente seleccionada como fuente activa. Parámetros de entada:

- Sizex: Tamaño horizontal de la fuente seleccionada. - Sizey: Tamaño vertical de la fuente seleccionada. - pBufferFont: Puntero al array que contiene los caracteres ASCII de la fuente

seleccionada. Estructura de la función: A partir del puntero al array de la fuente seleccionada como parámetro de entrada da valor al puntero global que indica la fuente activa. Da valor también a las variables globales que definen el tamaño horizontal y vertical de la fuente activa a partir de los valores introducidos en la función. Retorna: Retorna uno si el tipo de fuente seleccionada está disponible. Si no estuviese disponible retorna un cero. int SetRectangulo (unsigned ULx, unsigned ULy, unsigned LRx, unsigned LRy, UInt16 Color_vent); Objetivo: Dibujar el rectángulo de fondo de las ventanas. También se puede llamar esta función para dibujar rectángulos ajenos a ventanas. Parámetros de entada:

- ULx: Coordenada horizontal de la esquina superior izquierda de la ventana. - ULy: Coordenada vertical de la esquina superior izquierda de la ventana. - LRx: Coordenada horizontal de la esquina inferior derecha de la ventana. - LRy: Coordenada vertical de la esquina inferior derecha de la ventana.

Estructura de la función: Lo primero a aclarar para explicar la estructura de esta función es que si el contenido del rectángulo se pasa a pantalla en forma de words es para aprovechar la totalidad del ancho de bus que une el microcontrolador con el controlador de display del sistema. El segundo punto a aclarar es que el rectángulo no tiene porqué dibujarse a partir de una coordenada horizontal que sea múltiplo del cociente de la división 16/ bits por píxel seleccionados. Lo que se traduce en que el primer word a modificar en el display no contendrá cien por cien información del rectángulo, sino que lo hará tan solo parcialmente.

Page 62: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

62

Esto es debido al desplazamiento del rectángulo respecto a la posición múltiplo comentada. Este desplazamiento se arrastrará en cada uno de los words del rectángulo a pasar al display. Todo esto lleva a la necesidad de preparar los words a pasar al display aplicando máscaras y rotaciones de bits para adecuar el dibujo del rectángulo a las coordenadas introducidas. Explicados los dos puntos anteriores se pasa a una descripción secuencial de las acciones que se realizan en esta función. Se trata de manera independiente cada profundidad de color con el objetivo de dar mayor velocidad y transparencia al código, aunque conceptualmente se sigan los mismos pasos. A continuación se explicará el caso genérico. Se preparan las máscaras que posteriormente se aplicarán para el dibujo del primer, penúltimo y último word. Las máscaras se aplicarán sobre los words de la memoria de display, poniendo a cero los bits a modificar y a uno los que se quieren dejar inalterados. Se da valor también al word que se usará para dibujar el rectángulo. Por supuesto la información que contiene este word es de todos los píxels del mismo color, que será el que se ha seleccionado como parámetros de entrada.

Dentro de un bucle de tantas iteraciones como alto sea el rectángulo se escribe a cada iteración cada una de las líneas del rectángulo. Cada línea se compone del primer word de línea, de los words intermedios, del penúltimo y del último. Para el dibujo del primer word se siguen los siguientes puntos. Se calcula la dirección de memoria del word de display a modificar. Se aplica la máscara al word de display. Se prepara el primer word del rectángulo, aplicando el desplazamiento oportuno según la situación de éste, y dejando a cero los bits del word que no contienen información del rectángulo. Finalmente se realiza una OR entre el word del rectángulo y el word de display. Los words intermedios se tratan dentro de un bucle. Para dibujarlos se calcula la dirección de memoria del word de display a modificar. A continuación se vuelca el contenido del word del rectángulo, esta vez seguro que contendrá cien por cien información de rectángulo, en el word de display. Para el penúltimo word se calcula de nuevo la dirección del word de display a modificar. Se aplica la máscara calculada anteriormente. Se prepara el word del rectángulo, aplicándole la máscara inversa al word de display, para que lo que interese cambiar esté al valor correspondiente y lo que se quiera conservar a uno. Finalmente se realiza una OR entre el word del rectángulo y el word del display.

El último word se ejecuta exactamente igual que el penúltimo pero con su máscara propia.

Comentar el caso especial de la profundidad de color de 16 bits por píxel. En este caso no existe desplazamiento posible. Esto se debe a que cada píxel es representado por un word entero por lo que el dibujo de rectángulos con esta profundidad de color consiste en un simple volcado de words de rectángulo en los words de display. Evitando el tener que preparar y aplicar máscaras, así como preparar cada word del rectángulo antes de hacer el volcado en el word del display. Retorna: Uno si los parámetros pasados son correctos y cero si se ha pasado algún parámetro incorrecto. void ShowFullWindowText (UInt8 Id_Window); Objetivo: Escribir el texto asociado a la ventana en el interior de ésta, adecuándolo a sus dimensiones.

Page 63: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

63

Parámetros de entada:

- Id_Window: Identificador de la ventana seleccionada. Estructura de la función: En esta función se desarrolla un elevado número de acciones, las cuales se exponen secuencialmente a continuación. Para tener una visión global más clara se recomienda mirar el diagrama de flujo de la función que aparece en el apartado ‘4.3. Conexiones entre Funciones y Diagramas de Flujo’. Para mostrar la escritura del texto en la ventana hace falta el cálculo previo de una serie de parámetros. Estos parámetros son el número de caracteres por línea, el número de líneas de texto a escribir y el número máximo de líneas visibles de la ventana. Los caracteres por línea se calculan a partir de la dimensión horizontal de la ventana y del tamaño horizontal de la fuente de texto asociada a la ventana. El número de líneas de texto a escribir se extrae una vez se tiene el número de carácteres por línea y operando este valor con el valor del índice del último carácter escrito en pantalla. Si es la primera vez que se escribe en la ventana seleccionada el índice del último carácter escrito valdrá cero, lo que como más adelante se verá se traducirá simplemente en que se escribirá todo el texto desde el principio. El número máximo de líneas visibles de la ventana seleccionada se obtiene a partir de las dimensiones verticales de ésta y del tamaño vertical del carácter asociado a la ventana. Una vez calculados estos parámetros previos se realiza un seguido de acciones. Se acota el desplazamiento del texto, referido al valor máximo que puede adoptar la variable que indica el número de líneas que está desplazado el texto en su presentación en la ventana. Si el valor está por encima del máximo se restringe hasta éste. La justificación de esta operación es que no tiene sentido subir el texto por encima del inicio de escritura, una vez se está visualizando la primera línea carece de sentido seguir desplazando el texto hacia arriba. También se tiene en cuenta el caso en el que exista la petición de desplazamiento del texto cuando el texto a escribir cabe íntegramente en la ventana, en este caso el índice de desplazamiento de texto se pone a cero. Este último caso se daría comúnmente por ejemplo en situaciones de maximización de ventanas. A partir del valor del número de líneas de texto a escribir, del desplazamiento del texto en ventana y del tamaño de la línea de escritura de la ventana se calcula el índice de línea de escritura. Este índice indica a partir de que línea se ha de comenzar a escribir, para evitar la escritura inútil de texto que finalmente quedará oculto en la parte superior de la ventana. De este modo se escribe únicamente el texto visible. Lo cual hace que la operación de redibujar la ventana sea mucho más rápida y eficaz. Sobretodo en situaciones de extensos textos. Si existe una imagen de fondo asociada a la ventana se calcula su posición de inserción. El objetivo es dibujar la imagen centrada. La posición se calcula a partir del tamaño de la imagen junto con el tamaño de la propia ventana. Una vez conocida su ubicación se dibuja la imagen. Sabiendo a partir de que línea hemos de comenzar a escribir y cuantos caracteres tiene cada línea es inmediato saber a partir de que carácter se ha de comenzar a escribir. Por tanto se empieza a escribir el texto. Como ya se anunció anteriormente es posible que sea la primera vez que se escriba el texto en la ventana por lo que si es el caso de debe empezar a escribir desde el primer carácter de la cadena asociada a la ventana. Otra situación en la que se debe empezar a escribir desde el primer carácter es cuando el texto cabe íntegramente en la ventana o simplemente cuando el desplazamiento del texto sea el máximo y se pretenda visualizar el principio del texto.

Page 64: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

64

La escritura se hace dentro de un bucle que tiene tantas iteraciones como caracteres se tengan que escribir. La condición de salida del bucle será diferente según se deba escribir el texto íntegro o si por el contrario sólo se ha de escribir la parte visible. En el caso de que se deba escribir el texto íntegro la condición de salida del bucle será encontrar el carácter NULL, que indica el final de la cadena a escribir. Si entre medio la escritura llega al final de la ventana se empezará a rescribir el texto desde el principio de la ventana, pero esta vez desde una línea de texto más que la vez anterior. Por ejemplo si la vez anterior empezó a escribir desde el principio (línea 0) esta vez lo hará desde la línea 1. Visualmente es como si el texto fuera desplazándose hacia arriba pero por supuesto que a una velocidad muy elevada. Si por el contrario se ha de escribir sólo la parte visible del texto la condición de salida del bucle de escritura será que la escritura llegue al final de la ventana. Cuando lo haga habrá terminado de escribir. Por último se dibuja el marcador de altura de texto dentro de la barra de desplazamiento del marcador que se haya en la parte derecha de la ventana. Este marcador indicará a que tanto por ciento de altura se encuentra expuesto el texto. Si la ventana visualiza el final del texto el marcador estará debajo del todo por ejemplo. La altura a la que se dibuja este marcador se calcula por aproximación lineal según el valor de la variable que indica número de líneas que está desplazado el texto. void SetWindowText (UInt8 Id_Window, unsigned ULx, unsigned ULy,

unsigned LRx, unsigned LRy, UInt16 *pBufferFont, UInt16 FontColor, UInt16 BckColor, char *text, UInt8 SizeFontx, UInt8 SizeFonty, char *fname);

Objetivo: Inicializar, configurar y dibujar la ventana seleccionada. Parámetros de entada:

- Id_Window: Identificador de la ventana seleccionada. - ULx: Coordenada horizontal de la esquina superior izquierda de la ventana. - ULy: Coordenada vertical de la esquina superior izquierda de la ventana. - LRx: Coordenada horizontal de la esquina inferior derecha de la ventana. - LRy: Coordenada vertical de la esquina inferior derecha de la ventana. - pBufferFont: Puntero al array de carácteres ASCII del tipo de letra seleccionado. - FontColor: Código del color para la fuente. Para profundidades de color de 1, 2, 4

y 8 bits por píxel el color es un índice de la LUT. Para 16 bits por píxel el color está en formato RGB.

- BckColor: Código del color para el fondo de la ventana. Para profundidades de color de 1, 2, 4 y 8 bits por píxel el color es un índice de la LUT. Para 16 bits por píxel el color está en formato RGB.

- *Text: Puntero a la cadena de texto asociada a la ventana. - SizeFontx: Tamaño horizontal de la fuente de texto seleccionada para la escritura

en la ventana. - SizeFonty: Tamaño vertical de la fuente de texto seleccionada para la escritura en

la ventana. - *fname: Puntero a la imagen que saldrá centrada en el fondo de la ventana. Si no se

quiere imagen se pondrá la constante NOIMAGENFONDO. Estructura de la función: La función consiste en la asignación de valores a las variables de la estructura asociada a la ventana seleccionada según los parámetros de entrada. Cuando se sale de esta función la ventana consta como inicializada.

Page 65: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

65

Para que todas las configuraciones tengan efecto y se muestre la ventana en pantalla se llama a la función ‘SetWindowActive()’, seleccionando la misma ventana que se acaba de configurar. int SetWindowActive(UInt8 Id_Window); Objetivo:

Activar y redibujar, la ventana seleccionada. Al aplicar esta función a una ventana ésta pasa a estar en primer plano de la pantalla con el marco en color azul.

El marco de una ventana al activarse pasa a ser de color azul y el de la anterior ventana activa pasa a color negro.

Azul es el color del marco de la ventana activa y negro el color de las ventanas inactivas. Parámetros de entada:

- Id_Window: Identificador de la ventana seleccionada. Estructura de la función: Lo primero que se comprueba es que la ventana ya haya sido inicializada anteriormente, si no fuera el caso se sale de la función retornando un cero. Esto se justifica porque sin una inicialización previa no se dispone de los parámetros necesarios como para activar y dibujar la ventana. Si la ventana anteriormente activa no es el escritorio se redibuja el marco en color negro, que es color de las ventanas no activas. En el escritorio no se dibuja marco porque éste se considera el fondo de la pantalla. A continuación se pasa a dibujar la nueva ventana activa. Para ello primero se dibuja el rectángulo, después se dibuja el marco azul si la ventana seleccionada no es el escritorio, y por último se escribe el texto dentro la ventana y la imagen de fondo si la definición de la ventana seleccionada así lo indica. Esto último se realiza con el llamamiento a la función ‘ShowFullWindowText()’. Retorna: Retorna cero si la ventana seleccionada no había sido inicializada anteriormente. En caso de sí haber sido inicializada anteriormente retorna uno al salir de la función. void AddText(char * pText); Objetivo: Añadir texto a la ventana que se encuentra actualmente activa. El texto se añade a continuación del ya existente. Parámetros de entada:

- pText: Puntero a la cadena de texto que se quiere añadir a la ventana activa. Estructura de la función: Gracias a la variable de la estructura asociada a la ventana activa que indica el índice del último carácter de la cadena asociada a la ventana se sabe a partir de donde se debe añadir el nuevo texto. Se vuelca por tanto el contenido de la cadena de carácteres a añadir al final de la cadena de carácteres asociada a la ventana, formando a partir de ese momento parte ésta. Para que la ventana muestre el nuevo texto se pone a cero la variable de la estructura de la ventana que indica el desplazamiento del texto en la visualización de la ventana.

Por último se redibuja la ventana activa con el llamamiento a la función ‘SetWindowActive()’ seleccionando la ventana activa.

Page 66: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

66

void MoveUpText (Int16 m); Objetivo: Mover el texto m líneas hacia arriba o hacia abajo para poder visualizar líneas de texto ocultas en la parte alta o baja de la ventana. Parámetros de entada:

- m: Número de líneas a desplazar el texto hacia arriba o hacia abajo para poder visualizar texto no visible con la presentación actual de la ventana. El valor de m puede ser tanto positivo como negativo. Un valor positivo significará la visualización de la parte superior del texto y un valor negativo para la parte inferior.

Estructura de la función: Suma el valor de m a la variable perteneciente a la estructura asociada a la ventana activa que indica el desplazamiento del texto en la visualización de la ventana. void DrawFrame ( unsigned ULx, unsigned ULy, unsigned LRx, unsigned LRy, UInt16 FrameColor); Objetivo: Dibujar un marco alrededor de la ventana creada. Esta función es llamada por la función ‘SetWindowActive()’ cada vez que redibuja una ventana. Parámetros de entada:

- ULx: Coordenada horizontal de la esquina superior izquierda de la ventana. - ULy: Coordenada vertical de la esquina superior izquierda de la ventana. - LRx: Coordenada horizontal de la esquina inferior derecha de la ventana. - LRy: Coordenada vertical de la esquina inferior derecha de la ventana. - FrameColor: Color del marco.

Estructura de la función: Dibuja tantas líneas horizontales y verticales alrededor del rectángulo de fondo de la ventana como indica el grosor del marco. El valor de grosor de marco es una constante que se puede modificar según las preferencias del usuario. void MaxWindow(void); Objetivo: Maximizar la ventana activa, pasando ésta a ocupar la pantalla completa. Estructura de la función: La estructura asociada a cada una de las ventanas posee dos juegos de coordenadas. Un juego son las coordenadas actuales y otro son las coordenadas originales. Esta función lo que hace es modificar las coordenadas actuales dándoles los valores apropiados para que la ventana pase a ocupar toda la pantalla. Las coordenadas originales quedan inalteradas para poder deshacer los efectos de la maximización. Para hacer efectivo el cambio se redibuja la ventana activa actual con sus nuevas dimensiones. Lo que significa llamar a la función ‘SetWindowActive()’, seleccionando la ventana activa. void MinWindow(void); Objetivo: Minimizar la ventana activa. Estructura de la función: La estructura asociada a cada una de las ventanas posee dos juegos de coordenadas. Un juego son las coordenadas actuales y otro son las coordenadas originales. Estas últimas en el estado normal de la ventana son siempre las mismas que las actuales y nos sirven

Page 67: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

67

para poder deshacer los cambios que provoca la función ‘MaxWindow()’ o la ‘MinWindow()’. Por tanto lo que hace esta función internamente es volcar los valores de las coordenadas originales en las coordenadas actuales. Para hacer efectivo este cambio se redibuja la ventana escritorio y a continuación la ventana minimizada con sus nuevas dimensiones. En el código esto queda plasmado en dos llamadas a la función ‘SetWindowActive()’, la primera seleccionando el escritorio y la segunda la ventana minimizada. void RedimensionWindow(Int16 incx, Int16 incy); Objetivo:

Redimensionar la ventana que está activa en el momento de la llamada a función. La redimensión puede ser horizontal y/o vertical, a la vez que se admiten tanto incrementos como decrementos de tamaño. El texto se adecua automáticamente a las nuevas medidas de la ventana. Existirá siempre un tamaño mínimo, para que al menos quepa una letra; así como un tamaño máximo que vendrá determinado por los límites de la pantalla.

La redimensión se efectuará modificando la esquina inferior derecha, quedando la superior izquierda inalterada. Parámetros de entada:

- Incx: Píxeles que se incrementa la ventana horizontalmente sobre el margen derecho de la ventana.

- Incy: Píxeles que se incrementa la ventana verticalmente sobre el margen inferior de la ventana.

Estructura de la función: Si el incremento es negativo después de aplicarlo se comprueba que la ventana no

se reduzca por debajo de un límite inferior, si es el caso el nuevo tamaño de la ventana será el mínimo. Para ello se asignará a la coordenada de la esquina inferior derecha el valor de la coordenada de la esquina superior izquierda más el tamaño mínimo definido. Si por el contrario al aplicar el incremento obtenemos una coordenada que sobrepasa el margen de la pantalla, la nueva coordenada hará que la ventana se ajuste al margen de la pantalla. Esta operación se realiza de forma secuencial e independiente, primero con la coordenada horizontal y acto seguido con la vertical.

Para hacer efectivo el cambio se deberá volver a redibujar la ventana con los nuevos valores de coordenadas. Para ello se tiene en cuenta si la ventana se ha agrandado o si se ha reducido. Si se ha agrandado basta con hacer un llamamiento a la función ‘SetWindowActive( )’, seleccionando la ventana que se acaba de modificar. Si en cambio se ha reducido la pantalla no bastará con redibujar la actual pantalla, ya que quedarán vistos los antiguos márgenes del anterior tamaño de la ventana, por tanto habrá que redibujar la ventana de fondo, escritorio, y finalmente redibujar al ventana modificada. Para llevar a cabo esta acción se llamará dos veces a la función ‘SetWindowActive()’, una seleccionando el escritorio y otra seleccionando la ventana modificada. void MoveWindow(Int16 incx, Int16 incy); Objetivo: Desplazar la ventana que está activa en el momento de la llamada a función tanto horizontal como verticalmente según indiquen los parámetros de entrada. Siempre sin modificación alguna del tamaño y contenido de la ventana. Parámetros de entada:

- Incx: Píxeles que se desplaza la ventana horizontalmente, puede ser un valor positivo o negativo.

Page 68: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

68

- Incy: Píxeles que se desplaza la ventana verticalmente, puede ser un valor positivo o negativo.

Estructura de la función: Lo primero que comprueba es sin con los parámetros de entrada pasados se sale la ventana por abajo y/o por la derecha de la pantalla. Si es el caso reduce el incremento lo necesario para que la ventana se ajuste al borde inferior y/o derecho pero que no se salga. A continuación, comprueba si por el contrario con los parámetros pasado la ventana se saldría de la pantalla pero por arriba y/o por la izquierda. Este es el caso de incrementos negativos de módulo muy elevado. Si es el caso aumenta el incremento lo suficiente para que la ventana se ajuste al borde superior y/o izquierdo pero que no se salga.

Por último, una vez reajustados los incrementos, si hubiese sido necesario, se modifican los valores de la estructura asociada a la ventana activa. Los valores modificados concretamente son los que definen las coordenadas horizontales y verticales de la esquina superior izquierda e inferior derecha de la ventana. A los valores horizontales se les aplica el incremento horizontal y a los verticales el incremento vertical. Al aplicarles a las dos coordenadas horizontales el mismo incremento la ventana no modifica su tamaño, lo mismo pasa con las coordenadas verticales.

Para hacer efectivo este cambio se redibuja la ventana escritorio, para que no queden visibles los restos de la ventana tratada en su anterior posición y a continuación se redibuja de nuevo la ventana que se está tratando. En el código esto queda plasmado en dos llamadas a la función ‘SetWindowActive()’, la primera seleccionando el escritorio y la segunda la ventana minimizada.

void SetPixel (Int32 x, Int32 y); Objetivo: Escribir un píxel en la posición x, y indicada usando el color de escritura que esté actualmente activo. Parámetros de entada:

- x: Coordenada horizontal del píxel a escribir. - y: Coordenada vertical del píxel a escribir.

Estructura de la función: La escritura de píxels se realiza mediante el llamamiento a diferentes funciones según sea el valor de la variable global que marca los bits por píxel activos en el sistema. Las diferentes funciones son _PixelXbpp(), siendo X el valor de bits por píxel para el que está destinada la función. void _Pixel1bpp (Int32 x, Int32 y); void _Pixel2bpp (Int32 x, Int32 y); void _Pixel4bpp (Int32 x, Int32 y); void _Pixel8bpp (Int32 x, Int32 y); void _Pixel16bpp (Int32 x, Int32 y); Objetivo: Escribir un píxel en la posición x, y indicada usando el color de escritura que esté actualmente activo, usándose cada función para la profundidad de color para la que está destinada. Parámetros de entada:

- x: Coordenada horizontal del píxel a escribir. - y: Coordenada vertical del píxel a escribir.

Estructura de la función:

Page 69: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

69

Para la escritura de un píxel se referencia en primer lugar su dirección. El direccionamiento mínimo es de un byte. Para los casos de 1, 2 y 4bpp se aplican máscaras en el byte de display a modificar con el objetivo de modificar tan sólo el píxel deseado dentro byte direccionado. En segundo lugar se prepara el valor del byte que se quiere pasar a la memoria de display, de forma que queden los bits deseados en la posición del píxel a modificar. Una vez preparado el byte de memoria de display y el valor a aplicar se realiza una OR entre ambos y el resultado se asigna al byte de display.

En el caso de las profundidades de color de 8 y 16bpp se direcciona un byte y un word respectivamente. Como el píxel corresponde en los dos casos íntegramente al direccionamiento realizado no se ha de aplicar ningún tipo de máscara ni preparación, por lo que se realiza la asignación del color activo directamente.

Page 70: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

70

6. Análisis En este apartado se analizan los resultados obtenidos en cuanto a velocidades de escritura y dibujo en pantalla. Se presentan los resultados conseguidos, se valoran y se justifica su valoración. También se explican las pruebas realizadas para la comprobación del correcto funcionamiento del software de comunicaciones. Como muestra del funcionamiento global del sistema se presenta y explica una demo del software desarrollado. Se distinguen seis subapartados:

• Comprobación del software de comunicaciones. • Velocidad de escritura de texto. • Velocidad de dibujo de bitmaps. • Velocidad de dibujo de rectángulos. • Velocidad de dibujo de ventanas. • Explicación y muestra de una demo del software desarrollado.

Page 71: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

71

6.1. Comprobación del Software de Comunicaciones En el proyecto se ha desarrollado un software de comunicaciones mediante los puertos serie, pero debido a que el sistema al que pertenece este proyecto aún está incompleto la comunicación no ha tenido la oportunidad de ser usada dentro del sistema. Esto no tiene que significar en ningún caso que la comunicación pueda estar llena de errores, por ello de alguna manera debe ser comprobada. Con esta finalidad además de la propia de ayuda como herramienta durante el desarrollo, se ha usado la aplicación de comunicaciones para el puerto serie Terminal.exe. Gracias a esta aplicación se han podido enviar tramas al sistema, aún teniéndolas que construir y codificar manualmente. También se ha podido comprobar lo que enviaba el propio sistema ya que la aplicación permite tanto el envío como la recepción de tramas. Para comprobar la buena descodificación y codificación de las tramas se ha hecho que la función funApp() (que es la función que se llama una vez se ha completado la recepción de las tramas) vuelva a enviar lo mismo que ha recibido. Como a esta función tan sólo le llegan los bytes de datos previamente descodificados, al hacer el reenvío se vuelve a construir la trama, volviendo a codificar los bytes que así lo requieran. A la aplicación llega justo lo que se le había enviado. Esto es una fiable señal de que tanto los procesos de construcción como de interpretación de tramas funcionan perfectamente.

Para dar más credibilidad a las pruebas se han hecho ensayos que requiriesen muchos bytes a codificar incluyendo codificación en todos los campos posibles..

También se ha probado de enviar y recibir simultáneamente tramas por los dos puertos a la vez. El resultado es que como tanto la transmisión como la recepción funcionan por interrupción no hay ningún tipo de problema con la simultaneidad de envíos.

La realización de la transmisión y recepción mediante interrupción también permite que el microcontrolador no se quede pendiente de las comunicaciones sino que pueda seguir con el desarrollo de otras tareas.

Como conclusión de las pruebas realizadas con las comunicaciones se extrae que son fiables, robustas y eficientes.

Page 72: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

72

6.2. Velocidad de Escritura de Texto El texto es uno de los componentes principales de una ventana, aparte del

rectángulo y de la posible imagen de fondo. La velocidad de escritura de texto es la que más limita la velocidad de dibujo de ventanas.

Esta velocidad es independiente de los bits por píxel que estén activos ya que cada píxel perteneciente al carácter a escribir en pantalla se envía por separado, lo que significa que se hará un envío por el bus entre el microcontrolador y el controlador de display tanto si el píxel se representa con un bit como si se representa por 16. Sería laborioso y poco provechoso tratar de enviar la información de los caracteres en words. Como mucho se podría conseguir el envío de la información de una línea de carácter en cada envío, pero para ello sería necesario crear y aplicar máscaras en cada uno de los words, esto sumado a que en la mayoría de las líneas de los caracteres tan solo hay uno o dos píxeles con información hace que no sea considerada esta opción. El uso de máscaras sería necesario porque el fondo del carácter se requiere que sea transparente y el color de escritura debe ser configurable.

Sí depende del tamaño de carácter, contra más grande sea el tamaño de carácter más píxels se tendrán que escribir para representar un mismo número de caracteres, aunque si se mira desde el punto de vista de escritura de una ventana (tamaño de área determinado) no existe una asociación directa entre el tiempo de escritura y el tamaño del carácter.

En la figura 19 se muestran las tres fuentes de letra usadas en el proyecto.

Figura 19. Fuentes empleadas en el proyecto.

Para las pruebas realizadas en este apartado se ha tenido en cuenta la velocidad según el tiempo de escritura por pantalla (tiempo escritura / unidad de área), la razón es que cuando se dibuja una ventana, exceptuando la primera vez (ver apartado ‘5.3. Funciones de la Tercera Capa’), el texto que se escribe es el que cabe en el área de la ventana. Esto lleva a que lo importante de la velocidad de escritura es el tiempo que se tarda en llenar un área (área de la ventana normalmente). En la tabla 3 se muestra la velocidad de escritura del sistema según el tiempo que tarda en llenar un área con diferentes tamaños de carácter.

Bits por píxel Tamaño

carácter Escritura de 10 pantallas completas (640x480)

Escritura de una ventana (200x200)

Independiente 8x13 7.3 segundos 95 ms Independiente 10x16 6.5 segundos 85 ms Independiente 12x20 8.6 segundos 112 ms

Tabla 3. Velocidades de escritura en pantalla. Como ya se había comentado con anterioridad no existe una relación clara entre tamaño de carácter y área a escribir, ya que depende de más de un factor. Lo importante de la información extraída de la tabla 3 es el tiempo medio de escritura de una ventana entera de tamaño ‘normal’ es de menos de una décima de segundo. Es un tiempo más que aceptable para el uso al que está destinado el sistema.

Page 73: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

73

6.3. Velocidad de Dibujo de Bitmaps. Los resultados en cuanto a velocidades obtenidas en el dibujo de bitmaps en

pantalla se exponen en la tabla 4. Las imágenes con las que se han realizado las pruebas han sido de diferentes tamaños, y dependiendo del tamaño de la imagen hará falta mayor número de éstas para llenar una pantalla, lo que supone un mayor número de llamadas a función. En cuanto a las pruebas realizadas con las profundidades de color de 8bpp y 16bpp se han realizado con pantallas más pequeñas, ya que el controlador de display no puede soportar la configuración 640x480 con estas profundidades de color, por tanto se ha hecho una aproximación teniendo en cuenta la diferencia de áreas cubierta. Con estos razonamientos se quiere dar a entender que los resultados obtenidos son aproximados y dependerán de muchos factores pero no deja de ser cierto que son una buena estimación sobre la velocidad del sistema en el dibujo de bitmaps.

Bits por píxel Tiempo necesario para el

dibujo de 50 pantallas Dibujo de un bitmap (200x200)

1bpp 4 segundos 10.42 ms 2bpp 5.5 segundos 14.32 ms 4bpp 12 segundos 31.25 ms 8bpp 17 segundos 44.27 ms 16bpp 20 segundos 52.08 ms

Tabla 4. Velocidades obtenidas en el dibujo de bitmaps. Para interpretar estos resultados se han de tener en cuenta varios aspectos. El

primero es que contra más resolución tenga una imagen mayor número de words contendrá y por tanto mayor número de words tendrán que ser enviados desde el microcontrolador al controlador de display. Por otra parte contra más profundidad de color tenga la imagen la preparación de los words a enviar al controlador de display es menor, adoptando su máximo exponente en 16bpp donde se trata de un simple volcado de words sin preprocesación alguna. La dependencia de dos factores sumado a que el segundo factor no aumenta linealmente hace que el tiempo de dibujo de bitmaps respecto a los bits por píxel de éstos tampoco aumente de una forma lineal.

Los resultados conseguidos se consideran buenos. Sería posible rebajar el tiempo de dibujo de bitmaps pero sería a costa de generar un código muy extenso. Una discusión más detallada sobre el incremento o decremento de la velocidad en el dibujo de bitmaps se encuentra en el apartado ‘7.2. Mejoras en la Muestra en Pantalla de Bitmaps y Rectángulos’

Page 74: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

74

6.4. Velocidad de Dibujo de Rectángulos. Las velocidades obtenidas en el dibujo de rectángulos en pantalla se exponen en la

tabla 5. Los rectángulos con los que se han realizado las pruebas han sido en las profundidades de color de 1, 2 y 4bpp de pantalla completa, pero en las profundidades de 8 y 16bpp han sido de un tamaño inferior, debido a que el dispositivo controlador de display no soporta configuraciones de 640x480 con más de 4bpp. Por tanto los resultados obtenidos con 8 y 16bpp han sido aproximados teniendo en cuenta la diferencia de áreas cubiertas, aunque no se alejan mucho de la realidad.

La importancia de las velocidades conseguidas en el dibujo de rectángulos radica principalmente en que son uno de los procesos en el dibujo de ventanas que más recursos emplea.

Bits por píxel Tiempo necesario para el

dibujo de 150 pantallas Dibujo de una pantalla (200x200)

1bpp 3.5 segundos 3.00 ms 2bpp 5 segundos 4.30 ms 4bpp 12 segundos 10.42 ms 8bpp 23 segundos 19.92 ms 16bpp 46 segundos 39.97 ms

Tabla 5. Velocidades obtenidas en el dibujo de rectángulos. Para interpretar estos resultados se han de tener en cuenta varios aspectos. El

primero es que contra más resolución se defina en el sistema mayor número de words deberán ser enviados para el dibujo de un rectángulo del microcontrolador al controlador de display. Por otra parte contra más profundidad de color se defina la preparación de los words primero, último y penúltimo de cada línea a enviar al controlador de display es menor, adoptando su máximo exponente en 16bpp donde se trata de un simple volcado de words sin preprocesación alguna. La dependencia de dos factores sumado a que el segundo factor no aumenta linealmente hace que el tiempo de dibujo de rectángulos respecto a los bits por píxel tampoco aumente de una forma lineal.

La mejora de velocidad respecto al dibujo de bitmaps, la comparación se debe a la similar estructura de las funciones para dibujar imágenes y rectángulos, se justifica principalmente con que en el dibujo de rectángulos los words intermedios no se han de preparar tratándose pues el proceso de un simple volcado.

Los resultados conseguidos se consideran más que suficientes. Sería posible rebajar el tiempo de dibujo de rectángulos pero sería a costa de generar un código muy extenso. Una discusión más detallada sobre el incremento o decremento de la velocidad en el dibujo de rectángulos se encuentra en el apartado ‘7.2. Mejoras en la Muestra en Pantalla de Bitmaps y Rectángulos’

Page 75: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

75

6.5. Velocidad de Dibujo de Ventanas El tiempo de dibujo de una ventana vendrá determinado por la suma de los tiempos de dibujo de los diferentes componentes de ésta. Entre estos componentes se hayan el dibujo del rectángulo de la ventana, del marco, de la escritura del texto y de la posible imagen de fondo de la ventana. Como es de suponer todo dependerá también del propio tamaño de la ventana, de la longitud del texto de ésta, de si se ha de escribir todo el texto (haciendo referencia a largas cadenas de caracteres que no caben en la ventana) o si simplemente se escribe la parte visible (ver apartado ‘5.3. Funciones de la Tercera Capa’), y de si la ventana tiene asociada una imagen de fondo o no. La situación donde más se evidencia la limitación en la velocidad de dibujo de ventanas es al realizar un movimiento continuo de una ventana (muchos movimientos pequeños seguidos), esto se debe a que es preciso redibujar muchas veces tanto la ventana de escritorio como la ventana que está siendo movida. Como efecto visual se observa un parpadeo de la ventana, este parpadeo aunque es totalmente apreciable no es excesivo por lo que la velocidad de dibujo de ventanas se califica como adecuada.

Page 76: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

76

6.6. Demo A continuación se incluye el código del archivo principal del software del proyecto. Se trata de un programa ‘demo’ que hace uso de las más importantes funciones desarrolladas con el objetivo de dar una muestra de la funcionalidad cubierta. Los resultados de la simulación del software se adjuntan en formato vídeo en el CD recopilatorio del proyecto. Los comentarios sobre la intención de cada uno de los pasos del programa se encuentran comentados justo antes de cada acción. #include <intrinsics.h> #include <iolpc2294.h> #include "EpsonLib.h" #include "lpc2294.h" #include "Graphic.h" #include "Imagenes.c" // Funciones globales void esperar (UInt8 segundos); void funTimer0 (); void (*OldVect)(); extern unsigned short Font_Type_LC_12[]; extern unsigned short Font_Type_LC_10[]; extern unsigned short Font_Type_LC_8[] ; int espera=0; int main (void) { // Declaración de las cadenas de carácteres

// NUM_CHARS es una constante que marca el numero de caracteres que // se reservan para cada ventana

char Txt_Vent1 [NUM_CHARS] = "Texto de la VENTANA 1."; char Txt_Vent2 [NUM_CHARS] = "Texto de la VENTANA 2. Pongo mucho… char Txt_Vent3 [NUM_CHARS] = "Texto de la VENTANA 3."; char Add_Vent1 [] = " Anado este texto a la ventana 1. Anado este text… char Add2_Vent1[] = "Ultimo texto anadido."; char Normal [] = "Texto normal para comparar con los siguientes"; char Negrita [] = "Texto escrito en negrita"; char MasNegrita[] = "Texto con letra aun mas gruesa"; char Subrayado [] = "Texto subrayado"; char Subrayar [] = "________________"; // System initialization LPC2294SystemInit(); // Setup PLL int r; r = PllSetup(10, 60); __disable_interrupt(); // Setup and config UART0 ComCfg (COM_PORT_0,COM_BPS_9600,COM_BITS_8,COM_STOP_1, COM_PAR_NoPar,

ComAttUartRx0, ComAttUartTx0); ComRxApp (COM_PORT_0, funApp0); // Setup interrupt controller.

Page 77: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

77

LPC2294InitVIC(); VectSet (INTVECT_NV_UART0 ,AttInt_UART0 ); VectSet (INTVECT_NV_TIMER0,AttInt_Timer0); __enable_interrupt(); ComOpen(COM_PORT_0); //--- EPSON --------------------- // Config Display y creación del Escritorio (ventana 0) CfgDisplay (EPSON_MEM, EPSON_REG, COLOR, BPP_4, 640, 480); esperar (8); // Creación de la ventana 1 SetWindowText(1, 100, 100, 300, 230,Font_Type_LC_8, 0x04, 0x0e,

Txt_Vent1,8,13,NOIMAGENFONDO); esperar (8); // Añadir texto a la ventana activa (ventana 1) AddText (Add_Vent1); esperar (8); // Redibujar la ventana 1 ver como sólo la parte visible del texto // se escribe de nuevo. SetWindowActive(VENTANA_1); esperar (8); // Visualizar parte no visible del texto moviendo el texto hacia arriba MoveUpText (4); esperar (8); // Desplazar el texo hacia arriba más allá del principio Ver como se // limita a enseñar el principio del texto (no tiene sentido subir más // el texto) MoveUpText (20); esperar (8); // Redibujar la ventana 1 ver como se conserva la configuración y // se sigue mostrando la misma parte de texto que antes. SetWindowActive(VENTANA_1); esperar (8); // Añadir más texto ver como automáticamente pasa a mostrarse lo // último escrito (Antes se estaba mostrando el principio del texto) AddText (Add2_Vent1); esperar (8); // Creación de la ventana 2 con imagen de fondo centrada. El texto // se escribe sobre la imagen. SetWindowText(2, 250, 200, 380, 320,Font_Type_LC_8, 0x00, 0xff, Txt_Vent2,8,13,imagen2); esperar (8); // Activación de la ventana 1 La ventana 1 se superpone a la 2 y la // dos (ahora inactiva) pasa a tener el marco de color negro. SetWindowActive(VENTANA_1); esperar (8); // Maximización ventana activa (ventana 1) el texto se adapta a las

Page 78: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

78

// nuevas dimensiones de la ventana. MaxWindow(); esperar (8); // Minimización ventana activa (ventana 1) La ventana 1 vuelve a su // tamaño anterior, readaptando de nuevo el texto a la nueva ventana. MinWindow(); esperar (8); // Activar ventana 2 La ventana 2 se superpone de nuevo a la 1. SetWindowActive(VENTANA_2); esperar (8); // Redimensionamiento ventana activa (ventana 2) // Un poco No hay problema con los límites de la pantalla. RedimensionWindow(100, 30); esperar (8); // El incremento de la ventana no cabe en pantalla se ajusta al // borde de la pantalla sin dar ningún tipo de problema. RedimensionWindow(400, 400); esperar (8); // Movimiento de ventana activa (ventana 2) Se desplaza la ventana 2 // sin alterar su tamaño. // Un poco según el movimiento ordenado no se sale de la pantalla. MoveWindow(-20, -20); esperar (8); // Movimiento excesivo, se sale de pantalla se ajusta a los bordes // manteniendo de nuevo su tamaño inalterado. MoveWindow(-400, -400); esperar (8); // Creación de la ventana 3 muestra simultánea de las tres ventanas // más el escritorio. La ventana activa es la única con el marco azul. SetWindowText(3, 350, 200, 500, 400,Font_Type_LC_8, 0xff, 0x04,

Txt_Vent3,8,13,NOIMAGENFONDO); SetWindowActive(VENTANA_1); esperar (8); // Muestra de posibilidades de escritura. Se escribe de forma // independiente a las ventanas. (este texto no pertenece a ninguna) SetWindowActive(ESCRITORIO); SetFont (Font_Type_LC_8,8,13); // Normal Se escribe un texto normal para compararlo con los otros WrDispText (Normal,100,150); // Negrita WrDispText (Negrita,100,180); WrDispText (Negrita,101,180); // Más negrita WrDispText (MasNegrita,100,210); WrDispText (MasNegrita,101,210); WrDispText (MasNegrita,102,210); // Subrallado WrDispText (Subrayado,100,240); WrDispText (Subrayar,100,240); //---- FIN EPSON ---------------- while (1==1){} }

Page 79: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

79

//Definición de funciones globales usadas en la demo. void esperar (UInt8 segundos) { TimSet (TIM_TIMER_0, segundos*1000, TIM_PERIODIC, funTimer0); while (espera == 1); TimStop (TIM_TIMER_0); espera = 1; } void funTimer0 () { espera = 0; }

Page 80: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

80

7. Ampliaciones y Mejoras Este proyecto es tan sólo el punto de partida de un gran proyecto con una funcionalidad muy extensa y ambiciosa. Por ello no tendría sentido su ejecución si no se tuviesen en cuenta las futuras ampliaciones que se pueden y se deben efectuar. Las ampliaciones se pueden catalogar de dos naturalezas. La primera sería ampliación/mejora de soporte software y la segunda estaría más vinculada a la consideración de otros dispositivos hardware como podrían ser un puerto de comunicaciones USB o la incorporación de una pantalla táctil. Las naturalezas de las dos divisiones expuestas son muy diferenciables, aunque como se verá con las propuestas que se citan en este apartado las dos naturalezas de mejora se entremezclan en varias ocasiones. Esto es debido a que muchas de las mejoras software que se le pueden añadir a este proyecto van ligadas a la inclusión de nuevo hardware. O de la programación del hardware ya existente. En general en las posibles mejoras software no se tiene límite, se podría pretender hacer de este sistema todo un editor de textos o un editor de imágenes por ejemplo, pero es fácil ver que un sistema empotrado no es el mejor sistema donde implementar según que nivel de funcionalidad gráfica y que para el uso industrial que se le pueda dar no tiene excesivo sentido. En cuanto a las mejoras asociadas a nuevo hardware comentar que son mejoras totalmente ajenas a este proyecto y proyectista pero que se mencionan a modo de descripción de contexto del proyecto.

Page 81: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

81

7.1. Posibles Mejoras en la Escritura de Texto Actualmente el texto que se escribe en las ventanas o directamente a pantalla se adecua automáticamente al tamaño de la ventana o pantalla. Detecta el principio y final de línea sin problemas. También se detecta cuando deja de caber en el interior de una ventana y debe irse desplazando hacia arriba. Todo esto es un primer paso, imprescindible por supuesto, pero existen otras funciones que se pueden considerar muy importantes. La escritura podría anticiparse al cambio de línea de manera que no partiese ninguna palabra. Esto sería posible leyendo por ejemplo de forma previa toda la línea de caracteres a escribir y cambiando de línea cuando se calculase que la siguiente palabra no va a caber. No acabaría todo aquí, ya que añadiría complicaciones a la hora poder mover el texto dentro de una pantalla para visualizar parte del texto no visible. La complicación vendría dada por el hecho de que de este modo no sería evidente saber cuanto texto hay escrito en pantalla. Debería haber un doble contador de caracteres. Uno sería para caracteres avanzados y otro para caracteres escritos. También se podría añadir otra pequeña mejora que sería no escribir el carácter espacio a principio de línea, sino que se ajustase al margen izquierdo. Esta mejora derivaría de la primera, ya que esto se podría hacer únicamente porque ya se sabría que si una palabra de la línea superior acaba justo en el margen derecho y la primera palabra de la línea actual empieza en el margen izquierdo no significa que la palabra esté cortada por falta de espacio en la línea superior. Esta nueva funcionalidad también requeriría el doble contador de caracteres. Añadir texto a partir de cualquier punto y no únicamente a final del texto anterior, como es el caso actual. Este cambio no sería muy complicado de realizar pero carece de sentido si no se realiza asociándolo a un dispositivo táctil como puede ser un ratón o pantalla táctil, ya que el usuario debería contar manualmente cuantos caracteres se han escrito hasta el punto de inserción del nuevo texto.

Por supuesto también es necesaria la escritura a tiempo real en pantalla. Aunque es evidente que para ello es imprescindible la incorporación de un teclado. Esta ampliación no es puramente software, de todas formas, como se ha explicado al comienzo de la sección de ampliaciones y mejoras, la naturaleza de las mejoras suele ser mixta. También se mencionó al comienzo de la sección que las ampliaciones software no tienen límite, será el uso al que vaya destinado el sistema y la propia capacidad de éste los que lo establezcan.

Page 82: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

82

7.2. Mejoras en la Muestra en Pantalla de Bitmaps y Rectángulos Como características generales actualmente para el dibujo de un bitmap se

diferencian las cinco profundidades de color que acepta el sistema (1, 2, 4, 8 y 16 bits por píxel). La imagen se va dibujando de word en word para aprovechar al máximo la capacidad del bus entre el microcontrolador y el controlador de LCD. Esto es un punto intermedio entre el compromiso velocidad de dibujo y compactación de código.

La mejora en este apartado según el uso que se le vaya a dar al sistema sería acercarse a uno de los dos extremos posibles.

Los extremos serían por un lado una función muy compacta y reducida pero muy lenta que consistiría en dibujar píxel a píxel e independientemente de la profundidad del color. En el otro extremo se encontraría una función que no sólo distinguiría los cinco casos de profundidad de color sino que también diferenciaría todos los casos de los diferentes desplazamientos de la imagen. Por ejemplo en el supuesto de 8bpp los diferentes desplazamientos serían el caso de que tan sólo los ocho últimos bits del primer word de display a dibujar contengan información de la imagen y el caso de que sean los 16 bits. Con la profundidad de 4bpp encontraríamos 4 casos diferentes, con 2bpp serían 8 y con 1bpp 16. Como se puede entrever son muchas combinaciones diferentes que tratadas de forma independiente generarían un código muy extenso. A su favor tendría la alta velocidad de ejecución de la función ya que no haría falta la preparación de ninguna máscara, ya que serían de valor fijo, tampoco se encontraría la complejidad actual de la preparación de los word de la imagen.

En cuanto al dibujo de rectángulos se tiene exactamente el mismo escenario que con el dibujo de bitmaps. La estructura de las funciones es la misma y en la solución aportada en este proyecto comparten la misma postura de compromiso entre velocidad y compactación de código.

A parte de la búsqueda de la mejor relación entre compactación de código y velocidad de ejecución en la función para dibujar bitmaps, se podría añadir la posibilidad de adaptación automática de la profundidad de color de la imagen a los bits por píxel que estuvieran activos en el sistema. En esta primera fase, respecto a este tema, se ha supuesto que el usuario introduciría imágenes adecuadas a la profundidad de color según lo seleccionado anteriormente en el sistema.

Para lograr la adaptación automática de los bits por píxel de una imagen lo que se debería hacer sería que durante la preparación de los words de la imagen se tratara por separado los bits de cada píxel, añadiendo bits a uno si se tuviese que pasar a una mayor profundidad de color y eliminando los bits menos significativos si por el contrario se tuviese que restar profundidad de color. Este proceso ralentizaría sensiblemente la velocidad de dibujo de los bitmaps. La opción más lógica para este tema es que el usuario trate si fuese necesario las imágenes antes de pasarlas al sistema. Es la postura que se ha adoptado en este proyecto.

Page 83: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

83

7.3. Uso de Formatos de Imagen con Compresión En esta primera fase de desarrollo del sistema tan solo se trabaja con bitmaps, y estos no poseen ningún tipo de compresión de datos. Su interpretación, edición y tratado son relativamente sencillos pero pueden llegar a acarrear problemas de almacenamiento debido a insuficiencias de memoria. Si se quiere hacer una pantalla atractiva al usuario y se introducen muchas imágenes se encontrará esta traba.

Por lo expuesto anteriormente se explica la posibilidad de desarrollar una librería para el tratado de imágenes con otros formatos con compresión como el JPEG o el GIF, decantando la balanza en caso de elección por el JPEG. Su elección se debe a la escasa pérdida de calidad en compresiones elevadas. El trabajo con este tipo de formato no es sencillo, pero no deja de ser cierto que para futuras fases de este proyecto sí podría ser importante. Sin perder de vista tampoco la disminución de velocidad en el dibujo a pantalla de imágenes cuando poseen compresión, es obvio que el descomprimir una imagen necesita un tiempo de procesador. Este tiempo llegado el caso debería ser evaluado y decidir entonces sobre la viabilidad del uso de imágenes con compresión en el caso específico en el que se desarrollara.

Para más información sobre el formato gráfico JPEG consultar el apartado ‘Anexo II. Información sobre Imágenes JPEG’.

Page 84: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

84

7.4. Asociación de Funciones Gráficas a Dispositivos de Entrada. Para que el usuario pueda interactuar con el sistema se necesitará de la

incorporación de dispositivos de entrada como podrían ser un ratón, teclado o pantalla táctil.

Las posibles mejoras asociadas a la incorporación de dispositivos de entrada son muchas, muy interesantes y además imprescindibles para la interacción del usuario con el sistema.

Para las funciones de escritura como por ejemplo AddText() se podría asociar una llamada a esta función cada vez que se escribiese un carácter desde el teclado. Así se dispondría una escritura en pantalla a tiempo real, debido a que es más lento el tecleo del usuario que la actualización de la pantalla. También sería útil si se quisiera editar el texto asociado a una ventana sería necesario el teclado.

Para las funciones de redimensionamiento, movimiento, maximización y minimización de ventanas sería muy interesante que fueran asociadas a un ratón o a una pantalla táctil. Se podría hacer por ejemplo una zona sensible del marco de la ventana donde si se clica encima se maximice o minimice la ventana. O la esquina inferior derecha para el redimensionamiento. Para el movimiento de la pantalla podría ser sensible el resto del marco.

Para concretar alguno de los ejemplos expuestos anteriormente se comenta el caso de un redimensionamiento de ventana. Según la posición del cursor del ratón el sistema sabrá si se está en la zona sensible del marco de la ventana asociada a la redimensión de la ventana (se puede hacer que cuando el cursor del ratón esté situado sobre esta zona cambie de forma, para que el usuario sepa a ciencia cierta que se encuentra en la posición correcta). Si estando en la zona correcta se detecta una pulsación del botón del ratón se tomará muestra de las coordenadas exactas de la posición del cursor en el momento del pulso. A partir de entonces se esperará a que acabe el pulso, tomando en el momento del fin del pulso (el usuario suelta el botón) las nuevas coordenadas del cursor. Con las diferencias de coordenadas se calculará el nuevo tamaño de la ventana.

Page 85: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

85

7.5. Uso de los Puertos de Comunicación Serie El protocolo de comunicaciones del sistema mediante puerto serie está

implementado en el propio sistema pero es también necesaria su implementación en PC para posibilitar la comunicación con el sistema, actualmente aún no se ha implementado la aplicación para PC. Su implementación es imprescindible para posibilitar la conexión del sistema con PC para transmisiones de nuevas imágenes o nuevos juegos de fuentes por ejemplo. No obstante es importante no olvidar que la conexión con PC no dejará de ser eventual por el propio concepto del sistema.

Page 86: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

86

7.6. Implementación del Protocolo USB Este sistema consta físicamente de dos tipos de puertos para la comunicación con el usuario, son el puerto serie y el puerto USB. En cuanto a software tan solo se ha implementado el puerto serie. Para el tipo de transferencias que se llevan a cabo en el sistema el puerto serie es más que suficiente, sin sufrir por su menor velocidad de transmisión ningún tipo de restricción. El problema viene por otro enfoque, y es que para la comunicación eventual del usuario con el sistema se usarán mayoritariamente ordenadores portátiles, y en este tipo de ordenadores el puerto serie tiene una clara tendencia a desaparecer. Así pues, por querer evitar que el sistema quede anticuado, o simplemente cree problemas de mantenimiento por un simple conflicto de puertos se puede plantear la implementación software para el uso del puerto USB. La ampliación en resumen sería simplemente la programación de este protocolo que no se ha llevado a cabo en esta primera fase del proyecto. A parte del software para el propio sistema también sería necesaria la ampliación de la aplicación para PC que debería admitir los dos tipos de puertos.

Page 87: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

87

8. Entorno de Trabajo Durante la primera fase de desarrollo del proyecto se ha trabajado con una placa

evaluadora del microcontrolador, modelo phyCORE-LPC2292/94, esta fase ha ido en paralelo al desarrollo hardware de la propia placa del sistema. Las dos placas implementan el mismo microcontrolador, el modelo de microcontrolador es el LPC2294 de Philips.

En la primera fase se desarrolló la primera capa software del sistema ya que ésta tan sólo depende del modelo de microcontrolador utilizado. El entorno de desarrollo ha sido el mismo tanto en la primera fase donde se trabajaba con la placa evaluadora como en el resto del proyecto donde se ha trabajado con la placa propia del sistema. El entorno de desarrollo software ha sido el ARM IAR Embedded Workbench IDE. Para el desarrollo software a parte del propio entorno software se ha usado un debugger IAR L-Link-KS JTAG, con conexión a PC mediante USB.

Independientemente al desarrollo software del sistema se han tenido que crear las fuentes de letra para la escritura en pantalla. Estas fuentes han sido creadas a partir de imágenes que contenían todos los caracteres ASCII que se querían poder representar en pantalla. Estas imágenes han sido creadas en la aplicación Paint de Microsoft. Una vez creadas las imágenes, éstas se han interpretado y tratado para la creación de las fuentes de letra en el entorno Visual C.

Nombrar también el programa Hexedit.exe empleado para observar bitmaps en hexadecimal y comprender así mejor su estructura y contenido.

Por último queda mencionar el programa Terminal.exe utilizado para las pruebas de comunicación realizadas durante el desarrollo de las funciones de comunicación del puerto serie.

Page 88: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

88

9. Conclusiones La funcionalidad cubierta es bastante amplia aunque no hay que olvidar que este

proyecto es tan sólo una primera fase de desarrollo para un ambicioso producto como bien se da a entender en el apartado ‘7. Ampliaciones y Mejoras’.

Los resultados obtenidos han sobrepasado los objetivos iniciales marcados para este proyecto, por ello es remarcable el abasto de la funcionalidad alcanzada.

En cuanto a aspectos a mencionar sobre la realización del proyecto realzar la gran utilidad que aportó la placa evaluadora del microcontrolador, modelo phyCORE-LPC2292/94. Ésta se adquirió en la primera fase de desarrollo, cuando aún no se había desarrollado físicamente la placa del sistema. Permitió acortar mucho el tiempo de desarrollo del proyecto, ya que mientras se desarrollaba por un parte la placa propia del sistema se desarrolló en paralelo la primera capa software de éste, por no mencionar la familiarización con el entorno de desarrollo software.

En la etapa de desarrollo del hardware hacer nombramiento de un clásico en la elección de los componentes, este clásico es la elección de los componentes en base a lo estándar de los complementos necesarios para su implantación, más que en base a las propias ventajas que ofrece el componente. Esta situación se presentó por ejemplo en la elección del dispositivo controlador de display, donde se escogió el modelo S1D13A05 de Epson en vez del S1D13A06 por la dificultad de encontrar el tipo de memoria necesaria para el segundo.

Page 89: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

89

10. Bibliografía

• The complete reference C. Herbert Schildt. Osborne. • http://www.erd.epson.com • http://www.nxp.com • http://www.iar.com • http://www.jpeg.org • http://www.toshiba.com • http://www.hitachi-displays-eu.com • http://www.sharpsme.com • http://www.samsung.com • http://www.embedinfo.com • http://power.tdk.com • http://www.phycore.com • http://www.maxim-ic.com

Page 90: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

90

Anexo I. Información sobre Ficheros BMP Los ficheros gráficos con formato BMP (bitmap) son un estándar creado por

Windows, representan las siglas de BitMaP, mapa de bits. Todos los archivos de este formato tienen una estructura constante de una serie de campos. Estos campos empiezan con una cabecera, seguida de las propiedades de la imagen, a continuación figura una posible paleta de color y por último se encuentran los datos de la imagen.

En la tabla 6 se muestra una tabla resumen con el formato de este tipo de archivos.

Tabla 6. Formato de un bitmap.

En la tabla 7 se muestra el contenido de la cabecera.

Tabla 7. Información de la cabecera de un bitmap.

En la tabla 8 se encuentra la información del campo de propiedades de la imagen.

Campo bytes Descripción

Size 4 Tamaño de esta sección (siempre es de 40 bytes) Width 4 Anchura de la imagen en píxels Height 4 Altura de la imagen en píxels Planos 2 Número de planos (siempre es 1) BitCount 2 Bits por píxel (1, 4, 8, 16, 24) Compression 4 Tipo de compresión empleada (0, 1, 2) ImageSize 4 Tamaño de la imagen comprimida

(igual a 0 si no se comprime) XPixelsPerM 4 Resolución horizontal: píxeles por metro YPixelsPerM 4 Resolución vertical: píxeles por metro ColorsUsed 4 Número de colores usados, si hay paleta. ColorsImportant 4 Número de colores importantes (=0 si son todos)

Tabla 8. Campo de propiedades de un bitmap.

El campo de la paleta de color como se ha especificado anteriormente es opcional, esto se debe a que sólo aparece si el número de bits por píxel es menor o igual a 8. Si la profundidad de color es inferior o igual a ocho bits por píxel la información que se

Campo Tamaño de campo Cabecera 14 bytes Propiedades de la imagen 40 bytes Paleta de color Opcional, su tamaño puede variar Datos de la imagen Depende directamente del tamaño de la imagen

Campo Bytes Descripción Signature 2 Siempre es ‘BM’ FileSize 4 Tamaño del fichero Reserved 4 No se usa DataOffset 4 Posición relativa del comienzo de los datos de la imagen

Page 91: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

91

encuentra en el campo de datos de la imagen corresponde a un índice de la paleta. Por el contrario si es superior a ocho bits por píxel entonces los bits que representan a cada píxel del campo de datos contienen ya la información sobre el color de éste. Por ejemplo, en el caso de emplearse una profundidad de color de 24 y una compresión cero cada píxel se representa en 3 bytes, indicando el nivel de azul, verde y rojo respectivamente (i.e., cada nivel será un valor entre 0, que significa ausencia de ese color, y 255, que supone la máxima intensidad del color).

El tamaño de la paleta se calcula sabiendo el número de colores (ColorsUsed). Para la codificación de cada color se utilizan 4 bytes (Tamaño paleta = ColorsUsed x 4, unidad bytes); un byte para el azul, otro para el verde y otro para el rojo; el cuarto byte no contiene información.

En la tabla 9 se observa la estructura del campo de la paleta.

Tabla 9. Estructura de la paleta.

Resaltar el orden de los colores en la paleta. Los colores están invertidos en la paleta respecto al orden estándar RGB (rojo, verde, azul). En este caso primero se encuentra el azul y al final el rojo.

Finalmente, en el campo de datos de la imagen resalta el orden inverso de las líneas de la imagen, primero se almacena la última línea y por último la primera. También se ha de tener en consideración que cada línea ha de tener siempre un número de bytes múltiplo de cuatro, los bits o bytes que sobren no contendrán información sobre la imagen. Por último indicar que un bitmap siempre acaba con un byte a cero, éste es el byte de final de archivo.

Nº Color Byte 1 (Azul) Byte 2 (verde) Byte 3 (rojo) Byte 4 (vacío) 1 Intensidad

azul del color 1 Intensidad verde del color 1

Intensidad rojo del color 1

No contiene información

2 Intensidad azul del color 2

Intensidad verde del color 2

Intensidad rojo del color 1

No contiene información

3 Intensidad azul del color 3

Intensidad verde del color 3

Intensidad rojo del color 1

No contiene información

4 Intensidad azul del color 4

Intensidad verde del color 4

Intensidad rojo del color 1

No contiene información

Etc. … … … …

Page 92: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

92

Anexo II. Información sobre Imágenes JPEG El formato JPEG de imágenes corresponde con las extensiones .jpg y .jpeg. La

extensión .jpg es la misma que .jpeg; la primera proviene de una abreviación de .jpeg, con el motivo del requerimiento de muchas aplicaciones de reducir el campo de extensión a tres caracteres.

JPEG es, junto con GIF, uno de los formatos estándares en las páginas web, lo que ha hecho que su uso se dispare enormemente. Sus ficheros son válidos tanto para PC como para MAC, el formato es soportado por los navegadores más importantes (Internet Explorer y Netscape Navigator) y puede trabajar en escala de grises, RGB y CMYK.

Este formato de imágenes fue desarrollado por el Joint Photographic Experts Group, asociación de fotógrafos profesionales de Estados Unidos que buscaba un formato gráfico que permitiera el almacenamiento de imágenes fotográficas de calidad con un tamaño de fichero configurable y relativamente bajo.

Este objetivo se consigue usando el algoritmo de compresión con pérdidas JPEG, basado en el hecho de que el ojo humano no es perfecto y no es capaz de captar toda la información que se puede almacenar en una imagen de 24 bits. El formato JPEG intenta eliminar la información que el ojo humano no es capaz de distinguir, consiguiendo con ello factores de compresión cercanos a 20:1 sin pérdida apreciable de calidad (puede llegar hasta 100:1 y más). Este algoritmo es además configurable, por lo que se puede elegir cuanta compresión se quiere dar al fichero. Lógicamente, cuanto más grande sea ésta, menos calidad tendrá la imagen final.

La excesiva compresión produce muestras de color borrosas, así como una imprecisión en las zonas de mayor contraste. Un indicador directo del exceso de compresión es la presencia de áreas grises alrededor del texto negro sobre fondo blanco. Experimentando con el grado de compresión, se puede llegar a un porcentaje que suponga el mejor compromiso entre calidad y tamaño de fichero. Los programas gráficos permiten esta optimización de forma interactiva, mostrando una simulación del resultado con cada grado de compresión aplicado.

En la figura 20 se muestra una imagen que posteriormente ha sido excesivamente comprimida en dos ocasiones sucesivamente.

Figura 20. Imagen original

Page 93: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

93

En la figura 21 se muestra la misma imagen de la figura 20 pero con una compresión excesiva.

Figura 21. Imagen JPEG con una compresión excesiva.

En la figura 22 se vuelve a mostrar la misma imagen de la figura 20 pero esta vez

con una compresión extrema.

Figura 22. Imagen JPEG con una compresión extrema.

Una desventaja de trabajar con este formato es que las imágenes siempre sufren

algún tipo de pérdida, por lo que nunca vuelven a tener la calidad original. Recordar que el algoritmo por diseño es un algoritmo de compresión con pérdidas. Por ello es conveniente que una vez escaneada la imagen se almacene una copia en algún formato que permita compresión sin pérdidas, como BMP, con lo que se dispondrá de la imagen almacenada con su máxima calidad.

Page 94: Driver de un controlador gráfico - deeea.urv.catdeeea.urv.cat/public/PROPOSTES/pub/pdf/1048pub.pdf · Imagen con la fuente Lucida Console, ... Estructura de la paleta.....91 . 6

94

Si se abre un archivo JPEG, se modifica y luego se guarda de nuevo como JPEG, se producirá una nueva compresión del fichero, lo que provocará una apreciable degradación del archivo. Por esta razón es conveniente realizar las modificaciones necesarias en la imagen original antes de guardarla en formato JPEG.

El archivo JPEG se comprime al guardarlo en disco, pero debe ser descomprimido para utilizarlo en una aplicación. Esto significa que la cantidad de memoria que se necesita para manejar la imagen puede ser mayor que el tamaño del archivo guardado en varios órdenes de magnitud. Un archivo JPEG de 1 MB puede descomprimirse fácilmente en una imagen de 100 MB. Por este motivo, al abrir archivos JPEG, se produce una reducción en las prestaciones del sistema debido al tiempo requerido para procesar la compresión y la descompresión. Esta razón es la que dificulta en mayor medida el posible uso de este tipo de formato de imágenes en este proyecto.

JPEG es un formato especialmente adecuado para imágenes con muchos colores y con gradaciones de tonos, como las fotografías o las digitalizaciones de alta calidad. Si se usa para almacenar imágenes de tipo vectorial o dibujos sencillos, se observará como la compresión disminuye enormemente y las modificaciones hechas sobre la imagen original son apreciables a simple vista.

En el caso de imágenes a color trabaja con profundidades de color de 24 bits separados en tres canales (RGB), por lo que permite casi 16,8 millones de colores (color verdadero). En el caso de imágenes en escala de grises trabaja con un solo canal de 8 bits.

No permite el uso de transparencias (no maneja canales alfa) ni animaciones, pero sí que permite el uso de compresión progresiva, donde muestra la imagen gradualmente mientras la descarga el explorador web, utilizando series de lecturas para mostrar versiones cada vez más detalladas de toda la imagen, hasta que se han descargado todos los datos. Este aspecto podría resultar útil en el proyecto, pero antes, como ya se ha comentado debería comprobarse que el esfuerzo de compresión y descompresión que este tipo de archivos requiere al sistema sea compatible con el mismo.