TETRIS: UN ROMPECABEZAS BASADO EN EL MCF5272

Transcripción

TETRIS: UN ROMPECABEZAS BASADO EN EL MCF5272
Departamento de Ingeniería Electrónica
E.T.S.I. de Telecomunicación
Universidad Politécnica de Madrid
Laboratorio de Sistemas Electrónicos Digitales
Enunciado de la práctica
estándar del Laboratorio de
Sistemas Electrónicos
Digitales (LSED)
Coldtrix: un rompecabezas
basado en el MCF5272
Plan 94. Curso 2009-2010. Versión 1.1
Autores:
Fernando Fernández Martínez
Juan Manuel Montero Martínez
Rubén San-Segundo Hernández
Luis Fernando D’Haro Enríquez
Juan Manuel Lucas Cuesta
Ricardo de Córdoba Herralde
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
ÍNDICE GENERAL
1.
INTRODUCCIÓN ............................................................................................................................................ 5
1.1
2.
AVISO INICIAL .................................................................................................................................................. 6
ESPECIFICACIÓN DE REQUISITOS DEL SISTEMA ............................................................................................. 6
2.1
ANTECEDENTES ............................................................................................................................................... 6
2.2
OBJETIVO GENERAL .......................................................................................................................................... 8
2.2.1 Casos de uso ......................................................................................................................................... 11
3.
SUBSISTEMA HARDWARE ............................................................................................................................13
3.1
3.2
3.3
3.4
3.5
3.6
MATRIZ DE LEDS ............................................................................................................................................ 13
FILTRADO DE LA SEÑAL .................................................................................................................................... 14
AMPLIFICADOR DE POTENCIA ............................................................................................................................ 15
CASCOS O AURICULARES .................................................................................................................................. 16
OBSERVACIONES ADICIONALES SOBRE EL HW DE ENTRADA/SALIDA .......................................................................... 16
ALIMENTACIÓN DE LOS SUBSISTEMAS ................................................................................................................. 16
4.
SUBSISTEMA DIGITAL BASADO EN EL MCF5272 ...........................................................................................16
5.
SUBSISTEMA SOFTWARE..............................................................................................................................17
5.1
MODELO DE REQUISITOS DE SW ....................................................................................................................... 17
5.2
MODELO DE OBJETOS ORIENTATIVO ................................................................................................................... 17
5.2.1 Tecla ..................................................................................................................................................... 17
5.2.2 Estado................................................................................................................................................... 18
5.2.3 Piezas ................................................................................................................................................... 18
5.2.4 Juego .................................................................................................................................................... 19
5.2.5 Leds ...................................................................................................................................................... 20
5.2.6 Relojes .................................................................................................................................................. 21
5.2.7 Melodía ................................................................................................................................................ 21
5.2.8 Resultados ............................................................................................................................................ 22
5.2.9 Pantalla ................................................................................................................................................ 22
5.2.10
Puerto .............................................................................................................................................. 23
5.2.11
Rutinas o métodos generales de los objetos de un sistema ............................................................ 23
5.3
MODELO DE DISEÑO ....................................................................................................................................... 23
5.3.1 Arquitectura del sistema SW ................................................................................................................ 23
5.3.2 Modelo dinámico orientativo ............................................................................................................... 24
5.3.3 Estructura obligatoria de procesos ...................................................................................................... 33
5.4
MODELO DE IMPLEMENTACIÓN ORIENTATIVO ...................................................................................................... 37
5.4.1 Codificación .......................................................................................................................................... 37
5.4.2 Ejemplo de una posible implementación del objeto relojes ................................................................. 39
5.4.3 ¿Cómo modificar un bit del puerto de salida?...................................................................................... 40
5.4.4 Optimización ........................................................................................................................................ 43
6.
DESCRIPCIÓN DE LA SESIÓN -1 (ANTES DE IR AL LABORATORIO B-043) ........................................................44
6.1
7.
COMENTARIOS SOBRE LAS CONEXIONES .............................................................................................................. 44
DESCRIPCIÓN DETALLADA DE LA SESIÓN 0 ...................................................................................................45
7.1
MÉTODO DE TRABAJO ..................................................................................................................................... 46
7.2
TUTORIAL INICIAL ........................................................................................................................................... 46
7.3
TUTORIAL DEL MANEJO DEL TECLADO DE LA PLACA TL04........................................................................................ 47
7.4
DISEÑO, IMPLEMENTACIÓN Y PRUEBA DE UN PRIMER PROGRAMA ............................................................................ 47
7.4.1 Estructura básica de los programas que desarrolle ............................................................................. 47
2
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
7.4.2 Subrutina para configurar el HW (hwInit) ............................................................................................ 48
7.4.3 Si tiene dudas o problemas... ............................................................................................................... 48
7.5
NOCIONES SOBRE DEPURACIÓN DE PROGRAMAS................................................................................................... 48
7.5.1 PASO 1: Obtención de una prueba fallida y previsión de la salida ....................................................... 49
7.5.2 PASO 2: Localización del error .............................................................................................................. 49
7.5.3 PASO 3: Determinación de la causa del error ....................................................................................... 50
7.5.4 PASO 4: Corregir el error ...................................................................................................................... 51
7.5.5 Consejos para errores no sistemáticos y ocasionales........................................................................... 51
7.5.6 Comentarios adicionales sobre depuración de programas .................................................................. 52
8.
DESARROLLO RECOMENDADO .....................................................................................................................53
8.1
HITOS Y SESIONES ORIENTATIVAS....................................................................................................................... 53
8.1.1 Sesión -1 ............................................................................................................................................... 53
8.1.2 Hito 1: Menús y visualización ............................................................................................................... 53
8.1.3 Hito 2: Movimientos ............................................................................................................................. 55
8.1.4 Hito 3: Colisiones .................................................................................................................................. 56
8.1.5 Hito 4: Melodía de juego ...................................................................................................................... 57
8.1.6 Hito 5: Sistema final ............................................................................................................................. 57
9.
MEJORAS CON PUNTUACIÓN PREDEFINIDA .................................................................................................58
9.1
9.2
9.3
9.4
10.
ESTADÍSTICAS DE JUEGO (MÁXIMO 0,3 PUNTOS) .................................................................................................. 58
GENERACIÓN ALEATORIA DE PIEZAS (MÁXIMO 0,3 PUNTOS) ................................................................................... 58
GENERAR LA SEÑAL DE CADA NOTA MEDIANTE EL DAC DE LA PLATAFORMA ENT2004CF (MÁXIMO 0,5 PUNTOS) ............ 58
CONSTRUCCIÓN DE UN PROTOTIPO DEL HW EN PCB (MÁXIMO 0,5 PUNTOS) ............................................................ 59
OTRAS MEJORAS .....................................................................................................................................59
10.1
10.2
10.3
10.4
10.5
10.6
10.7
10.8
10.9
10.10
10.11
10.12
10.13
10.14
10.15
10.16
11.
11.1
11.2
11.3
11.4
VELOCIDAD O RITMO DE CAÍDA VARIABLE: NIVEL DE DIFICULTAD INCREMENTAL........................................................... 59
AMPLIACIÓN DE LA FUNCIONALIDAD POR SW ...................................................................................................... 60
PERFIL DE JUGADOR ........................................................................................................................................ 60
VISUALIZADOR DE LA SIGUIENTE PIEZA ................................................................................................................ 61
SISTEMA DE PUNTUACIÓN AVANZADO ................................................................................................................ 61
COMIENZO DE JUEGO CON BLOQUES FIJOS .......................................................................................................... 62
AMPLIACIÓN DEL SUBSISTEMA DE VISUALIZACIÓN ................................................................................................. 62
COMUNICACIÓN SERIE UTILIZANDO LA UART ...................................................................................................... 62
CONEXIÓN CON UN SERVIDOR TFTP .................................................................................................................. 62
RECEPCIÓN DE MELODÍAS POR SMS.............................................................................................................. 63
CONTROL DEL JUEGO POR MEDIO DE UN ACELERÓMETRO .................................................................................. 63
REPRODUCCIÓN DE VOZ.............................................................................................................................. 63
RECONOCIMIENTO DE VOZ .......................................................................................................................... 63
PROGRAMACIÓN (MEDIANTE COMUNICACIÓN SERIE) DE UN KIT DE REPRODUCCIÓN MP3 ......................................... 63
COMUNICACIÓN CON UNA PSP, CON UNA PDA O UN IPOD ............................................................................... 64
IMPLEMENTACIÓN DE OTROS JUEGOS ............................................................................................................ 64
EVALUACIÓN ...........................................................................................................................................64
FUNCIONAMIENTO Y EXAMEN ORAL (<=4 PUNTOS O <=3,5 PUNTOS) ...................................................................... 65
MEMORIA FINAL (<=1,5 PUNTOS) .................................................................................................................... 65
CALIDAD DEL SW (<=2,5 PUNTOS) ................................................................................................................... 65
CALIDAD DEL HW (<=0,5 PUNTOS) .................................................................................................................. 67
12.
MATRÍCULAS Y DIPLOMAS DE HONOR ....................................................................................................67
13.
BIBLIOGRAFÍA..........................................................................................................................................68
3
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
ÍNDICE DE FIGURAS
FIGURA 1. EJEMPLOS DE DIFERENTES PLATAFORMAS CON TETRIS. ......................................................................................... 7
FIGURA 2. TECLADO MATRICIAL USADO EN EL LSED. .......................................................................................................... 10
FIGURA 4. DIAGRAMA DEL SUBSISTEMA HW DE VISUALIZACIÓN DE LA MELODÍA (8 FILAS Y 4 COLUMNAS). ................................... 14
FIGURA 5. PROPUESTA DE MONTAJE PARA LA IMPLEMENTACIÓN DEL AMPLIFICADOR DE POTENCIA. ............................................. 15
FIGURA 6. TIPOS DE PIEZA (FUENTE: SITIO WEB OFICIAL TETRIS, WWW.TETRIS.COM). ............................................................... 19
FIGURA 7. DIAGRAMA DE OBJETOS: ARQUITECTURA SOFTWARE. ........................................................................................... 22
FIGURA 9. MODELO MATRICIAL DE PIEZA: ÁREA DE OCUPACIÓN DE LA PIEZA............................................................................ 27
FIGURA 10. MODELO DE ROTACIONES PARA LAS PIEZAS. ..................................................................................................... 29
FIGURA 11. REFRESCO DE LA MATRIZ DE LEDS. .................................................................................................................. 30
FIGURA 12. REPRESENTACIÓN TEMPORAL DE LOS 3 PROCESOS. ............................................................................................ 34
ÍNDICE DE TABLAS
TABLA 1. FRECUENCIAS DE LAS NOTAS MUSICALES PARA LAS ESCALAS 4, 5, 6 Y 7. ...................................................................... 9
TABLA 2. ASIGNACIÓN ESTÁNDAR DE TECLAS PARA EL JUEGO EN EL TECLADO MATRICIAL DEL LSED. ............................................. 12
TABLA 3. DETALLE DE LAS DIFERENTES CONEXIONES AL PUERTO DE SALIDA. ............................................................................. 41
TABLA 4. RELACIÓN ENTRE SESIONES DE LABORATORIO E HITOS A CONSEGUIR. ........................................................................ 53
4
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
1. Introducción
El objetivo del Laboratorio de Sistemas Electrónicos Digitales es que el alumno adquiera
práctica en el desarrollo de sistemas con interacción entre HW y SW y con requisitos de tiempo
real, aplicando y consolidando de una manera práctica los conocimientos adquiridos principalmente
en las asignaturas de tercer curso Sistemas Electrónicos Digitales y Laboratorio de Circuitos
Electrónicos, partiendo de la base sobre programación adquirida en Fundamentos de la
Programación y Laboratorio de Programación.
Para ello deberá seguir las instrucciones aquí incluidas, que implicarán diversas fases de diseño,
análisis, implementación y medida de los circuitos y programas propuestos. Igualmente se hará
especial énfasis en que los alumnos adquieran una visión práctica de los problemas con los que se
encuentra el diseño del hardware (HW) y el software (SW) de sistemas electrónicos a la hora de
implementar prototipos reales de Laboratorio.
El resultado del trabajo realizado debe quedar reflejado en una memoria final que contenga los
detalles del proceso, así como los resultados obtenidos y todas aquellas cuestiones específicas que
se indiquen en el enunciado. Es obligatorio entregar electrónicamente el programa en
desarrollo a través del portal http://lsed.die.upm.es de acuerdo con las normas generales del
LSED [1] publicadas previamente.
Salvo que se indique lo contrario, la práctica propuesta contiene las especificaciones mínimas
obligatorias que deben cumplir los sistemas y serán valoradas con un máximo de 8 puntos si se
realiza en C y 8,5 puntos si se realiza en ensamblador. Esta nota máxima sólo se conseguirá si
se cumplen todas las especificaciones, y la memoria, el código, el hardware y las respuestas en
el examen oral son perfectos. La descripción del sistema de menús de la interfaz de usuario es
orientativa, aunque en la evaluación se valorará la calidad de la interfaz desarrollada. Las
desviaciones respecto a la interfaz de este enunciado deben ser explicadas en la memoria final.
Adicionalmente a las especificaciones mínimas, se presentarán sugerencias de mejoras
opcionales, dejando a los alumnos la libertad para que añadan nuevas mejoras o esquemas
alternativos. Con estas mejoras o montajes alternativos añadidos al prototipo básico, y dependiendo
de su dificultad y realización, se podrá alcanzar la máxima nota, 10 puntos. Añadir una mejora no
garantiza que la nota final esté por encima de 8 puntos si se realiza en C y 8,5 puntos si se realiza
en ensamblador; sólo ofrece la posibilidad de sumar puntos sobre la nota de la parte básica de su
sistema, de su examen oral y de su memoria final.
Sobre otras modalidades de práctica distintas de la estándar, remitimos al alumno a la
información general de la asignatura [1]. Aquellos alumnos que deseen realizar una práctica
innovadora basada en un problema o un diseño propios (o propuesto por un profesor), deberán
hablar con alguno de los profesores de la asignatura y presentarle (y ser aprobada por el mismo) una
propuesta de práctica donde describan en 2 o 3 páginas cuáles son los objetivos del sistema
propuesto, qué recursos son necesarios para llevarlo a cabo, así como las arquitecturas HW y SW
propuestas para la resolución del problema. No será admitida ninguna práctica (por muy compleja o
perfecta que sea) que no se ajuste a estas normas.
Sobre las consideraciones éticas del trabajo en el laboratorio, remitimos al alumno al documento
publicado sobre la filosofía de los laboratorios LCEL y LSED, disponible a través del portal de la
asignatura [2].
5
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Para cualquier consulta, no duden en dirigirse al coordinador Fernando Fernández Martínez (B109, [email protected]), o a cualquiera de los profesores del LSED en sus respectivos horarios de
tutoría. Podrá encontrar éste y otros documentos relacionados, así como información actualizada
sobre la asignatura, en http://lsed.die.upm.es/. Adicionalmente, el alumno dispondrá de un conjunto
de vídeos explicativos y demostrativos sobre esta práctica y este enunciado.
1.1 Aviso inicial
Cuando aborde la lectura de este documento, hágalo con tranquilidad y detenimiento. Frases o
comentarios que no se entiendan en una primera lectura pueden encerrar avisos y recomendaciones
que le serán útiles a lo largo del desarrollo del Laboratorio.
No se preocupe si no alcanza a comprender todos los términos, conceptos y detalles que se
discuten. Todos ellos se irán aclarando a medida que avance en la lectura de este documento. Por
supuesto, asuma que necesitará varias lecturas y una reflexión a fondo sobre todo esto.
Preste especial atención a todas las referencias explícitas a aspectos que se indican como
obligatorios para incluir en la memoria: no quiere decir que algo no referenciado explícitamente no
tenga que ser tratado, sino que nuestra experiencia demuestra que algunos de esos aspectos no son
considerados por un cierto número de alumnos, lo que da lugar a desagradables sorpresas en los
exámenes.
A lo largo de este enunciado irá descubriendo que multitud de detalles imprescindibles de
solventar en un sistema real, se dejan de lado o se simplifican notablemente. Es fundamental que
tenga en cuenta que esta práctica pretende ser un ejercicio de diseño, implementación y prueba de
sistemas electrónicos digitales (con una pequeña componente analógica), con lo que es seguro que
encontrará decisiones de diseño y recomendaciones que harían imposible que el prototipo final
construido pudiera llegar a formar parte de un sistema real.
2. Especificación de requisitos del sistema
2.1 Antecedentes
Uno de los sectores de mayor auge de la industria electrónica es el de los videojuegos. Buena
prueba de ello la constituyen los informes periódicos realizados por el consorcio Avista Partners
(http://avistapartners.com/news-newsletter.html). Según los datos recogidos en el informe
correspondiente al año 2009, a pesar de los efectos de la consabida crisis económica, se manejaron
cifras superiores a los 3500 millones de dólares en acuerdos dentro del sector, y unos 1200 millones
de dólares en adquisiciones.
En los últimos años, una de las piedras de toque que caracteriza a los videojuegos es el elevado
grado de complementariedad en el desarrollo de HW y SW especializados (lo que se refleja, en el
informe anterior, en la elevada aceptación de los juegos móviles que alcanza el 82,9%). Un segundo
rasgo distintivo del mercado actual de videojuegos es que, frente a juegos más tradicionales,
muchas veces de carácter violento o solitario, han surgido nuevos juegos de carácter más social,
cultural o colectivo, y que implican nuevos tipos de competiciones y de interacción física, nuevas
habilidades puestas en juego, nuevas interfaces, etcétera.
6
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Desde el punto de vista del HW, la gran revolución ha sido el Wiimote de Nintendo (que ha
cambiado incluso el perfil de los jugadores y compradores de videojuegos), con su capacidad para
detectar movimientos de manera inalámbrica y atraer nuevo público al mundo de las consolas. En
torno a él proponemos la realización de una práctica alternativa, y en esta práctica estándar
proponemos mejoras basadas en acelerómetros como los de dicho mando.
Más recientemente, ha sido Microsoft quien ha hecho pública su intención de provocar una
nueva gran revolución con el anuncio de la puesta marcha para el próximo verano de su Proyecto
Natal, una manera de jugar con la videoconsola Xbox360 sin mandos, simplemente empleando
gestos y la voz.
Para la práctica estándar de este curso académico no hemos contemplado cotas tan ambiciosas,
en su lugar hemos escogido como modelo un videojuego perteneciente al grupo de los “videojuegos
rompecabezas”. En este tipo de juegos, el objetivo es resolver un puzzle visual, empleando por lo
general modelos lógicos, estratégicos, reconocimiento de patrones y, en no pocos casos, habilidad
manual. Dentro de este tipo de videojuegos destacan, entre otros, el conocido Buscaminas, que se
puede encontrar en casi todas las distribuciones de Microsoft Windows, el conocido arcade
Bomberman, y el paradigma de este tipo de videojuegos, TetrisTM, creado en 1984 por el
programador ruso A. Pajitnov, y que constituirá el modelo de base a partir del cual se articula esta
práctica.
Figura 1. Ejemplos de diferentes plataformas con TETRISTM.
7
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
La mecánica de TetrisTM es muy simple: una serie de piezas, denominadas tetrominós,
descienden a una cierta velocidad por la pantalla de juego. El jugador tiene la posibilidad de rotar
las piezas según giros de 90 grados en sentido antihorario. Las piezas encajan unas sobre otras, y
entre los márgenes del tablero de juego. Siempre que se consigue formar una línea horizontal
completa (o más de una), dicha línea (o líneas) desaparecen, ocasionando que el resto de elementos
en la pantalla desciendan, e incrementando el contador de puntuación del jugador. Si, en un
momento dado, las piezas alcanzan el límite superior de la pantalla, el juego finaliza. La dificultad
del juego se puede ver incrementada por diferentes factores: velocidad de caída de las piezas,
posiciones iniciales del tablero ocupadas por piezas, aparición aleatoria de fragmentos de piezas en
posiciones aleatorias del tablero, etcétera.
Tal fue el éxito del videojuego, que innumerables versiones comenzaron a poblar las tiendas de
videojuegos, los ordenadores personales y los salones recreativos de todo el mundo. La influencia
de Tetris se deja notar incluso veintiséis años después de su creación, con versiones para
dispositivos tan actuales como el iPod de Apple, o incluso en internet en forma de “película” basada
en este videojuego (http://www.myvideo.de/watch/3983910/Tetris_Film_Trailer).
En la presente práctica supondremos que un cliente (el Departamento de Ingeniería Electrónica)
nos ha contratado para desarrollar un prototipo de un videojuego de rompecabezas de bajo coste,
inspirado en los anteriores. Dado que el propósito de este laboratorio es eminentemente docente
(con especial énfasis en la interacción HW-SW, así como en los requisitos de tiempo real), el
objetivo será implementar un prototipo funcional completo. Este enunciado constituye una guía
para su diseño e implementación.
2.2 Objetivo general
El objetivo de la práctica es mostrar la viabilidad de la idea de diseño básica desarrollando un
prototipo plenamente funcional. El programa que ejecutará el micro se realizará en ensamblador o
en C (ambos están incorporados en el entorno de desarrollo EDColdFire; la calificación máxima de
la práctica básica es 8 puntos si se realiza en C y 8,5 puntos si se realiza en ensamblador). El
sistema digital basado en un microprocesador será la plataforma ENT2005CF disponible en el
laboratorio B-043 (construida en torno a un MCF5272). Para más detalles relacionados con el
sistema de desarrollo, consulte la publicación [2].
En los apartados siguientes se detallarán las arquitecturas HW y SW, haciendo énfasis en la
descomposición modular del sistema, tarea clave para abordar con éxito el diseño de cualquier
sistema HW o SW medianamente complejo.
El objetivo general lo podemos resumir de la siguiente manera, desarrollar “un sistema digital
basado en la plataforma ENT2005CF” que permita:
•
Mostrar en una matriz de leds de 8x4, que hará las veces de display, el área de juego en
la que el jugador deberá ir encajando las piezas, diferentes formas geométricas
compuestas por cuatro cuadrados conectados ortogonalmente. Para ello empleará 12
terminales digitales de salida de la plataforma ENT2005CF (8 terminales para las filas y
4 terminales para las columnas). De esta manera, el jugador observará, sucesivamente,
cómo va “cayendo” una pieza tras otra a velocidad constante de la parte superior del
display. El jugador no podrá impedir la caída de las piezas pero sí que podrá
modificar tanto su orientación (i.e. ángulo de rotación de la pieza en sentido anti-horario
8
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
respecto a la base del área de juego, 0°, 90°, 180°, 270° respectivamente) como la
posición a ocupar dentro del área de juego.
•
Cuando el jugador consiga completar una o varias líneas horizontales, dichas líneas
deberán desaparecer. Al mismo tiempo, todas las piezas que estén por encima deberán
descender una posición, liberando espacio de juego y por tanto facilitando la tarea de
situar nuevas piezas. El juego acabará cuando las piezas se amontonen hasta rebasar
el límite superior del área de juego.
•
De manera indefinida (el programa nunca dejará de monitorizar el teclado hasta que se
apague el sistema), debe presentar al jugador un menú por pantalla que le permita
elegir tanto un nivel de dificultad concreto como el momento de comienzo del juego.
Una vez finalizada una partida, deberá volver al menú inicial.
•
El juego tendrá 3 niveles de dificultad entre los que el jugador deberá escoger:
o en el nivel 1 las piezas caerán a una velocidad estándar (e.g. uno o dos segundos
por línea);
o en el nivel 2 la velocidad de caída se acelerará, por ejemplo, un 20%;
o finalmente, en el nivel 3 dicha velocidad será un 40% mayor que la del nivel 1;
•
Medir el número de líneas horizontales completadas. Al terminar de jugar, el sistema
deberá mostrar esta información en la ventana de terminal del entorno de desarrollo
EDColdFire. Adicionalmente, y como una de las posibles mejoras, se sugiere la
ampliación del conjunto de resultados mostrados por pantalla (e.g. el tiempo de juego
medido en segundos y la relación entre ambos).
•
Reproducir una melodía monofónica (no es necesario reproducir varias notas a la vez),
durante el transcurso del juego. Cada nota de la melodía será un tono de la frecuencia y
duración adecuadas. En esta práctica, la plataforma ENT2004CF será la encargada de
generar una señal cuadrada con la frecuencia de la nota a reproducir durante un tiempo
determinado. Esta señal cuadrada será generada por el MCF5272 a través de la salida
TOUT0 del temporizador 0 (TIMER 0) que se corresponde con el PIN 13 del conector de
salidas digitales. Esta señal será aplicada sobre el HW analógico necesario para poder
escuchar correctamente el audio en unos auriculares y para regular el volumen de
reproducción. A continuación de la Tabla 1, donde se muestran las frecuencias
(redondeadas a números enteros) de las notas correspondientes a las 4 escalas con las que
vamos a trabajar en esta práctica, se incluyen las frecuencias (en Hz) y las duraciones de
las notas (en milisegundos) de la melodía propuesta.
Tabla 1. Frecuencias de las notas musicales para las escalas 4, 5, 6 y 7.
Número
0
1
2
3
Nota Silencio DO DO# RE
Octava 4
0
262 277 294
Octava 5
0
523 554 587
Octava 6
0
1047 1109 1175
Octava 7
0
2093 2217 2349
4
RE#
311
622
1245
2489
5
MI
330
659
1319
2637
6
FA
349
699
1397
2794
7
FA#
370
740
1480
2960
8
9
10
11
12
SOL SOL# LA LA# SI
392 415 440 466 494
784 831 880 932 988
1568 1661 1760 1865 1976
3136 3322 3520 3729 3951
9
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
En la versión final, los retardos debidos a, por ejemplo, escribir por pantalla o leer el
teclado no deben retardar la visualización de las piezas ni la reproducción de las notas, ni
la visualización y reproducción deben retardarse entre sí (requisito de concurrencia y
tiempo real).
Figura 2. Teclado matricial usado en el LSED.
•
Las teclas que debe aceptar el sistema serán al menos 4:
o las teclas ‘1’, ‘4’ y ‘7’ del teclado matricial servirán para elegir los niveles de
dificultad y para desplazar las piezas durante el juego. De este modo, una
pulsación de dichas teclas supondría un desplazamiento de la pieza actualmente
en movimiento hacia la izquierda, hacia abajo y hacia la derecha respectivamente
(siempre que dichos movimientos estén permitidos tal y como se verá más
adelante en la sección 5.3.2.7).
o la tecla ‘A’, que servirá para dar comienzo al juego o, una vez comenzado éste,
para girar o rotar la pieza en movimiento. En este último caso, sucesivas
pulsaciones de dicha tecla deberían provocar a su vez sucesivas rotaciones de la
pieza a intervalos de 90º con respecto a la base de la pantalla y en sentido antihorario.
•
Será, igualmente, competencia del sistema SW, generar y procesar las señales necesarias
para gobernar el HW externo.
En relación a la melodía disponible, ésta estará guardada en memoria en forma de arrays o tablas
de datos que contengan las frecuencias y las duraciones en milisegundos de cada una de las notas
que componen la melodía. Las frecuencias y duraciones correspondientes a las notas de la melodía
propuesta se facilitan a continuación:
•
Frecuencias “Tetris”={1319, 988, 1047, 1175, 1047, 988, 880, 880, 1047, 1319, 1175,
1047, 988, 988, 1047, 1175, 1319, 1047, 880, 880, 0, 1175, 1397, 1760, 1568, 1397,
1319, 1047, 1319, 1175, 1047, 988, 988, 1047, 1175, 1319, 1047, 880, 880, 0, 659, 523,
587, 494, 523, 440, 415, 659, 523, 587, 494, 523, 659, 880, 831}; /* En Hz */
•
Tiempos “Tetris”={450, 225, 225, 450, 225, 225, 450, 225, 225, 450, 225, 225, 450,
225, 225, 450, 450, 450, 450, 450, 675, 450, 225, 450, 225, 225, 675, 225, 450, 225, 225,
450, 225, 225, 450, 450, 450, 450, 450, 450, 900, 900, 900, 900, 900, 900, 1800, 900,
900, 900, 900, 450, 450, 900, 1800}; /* En ms */
10
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
2.2.1 Casos de uso
En el sistema SW habrá varios actores externos:
•
El teclado, a través del cual el usuario puede seleccionar el nivel de dificultad, el
comienzo del juego, y la orientación (i.e. rotación) o la posición de cada una de las piezas
que vayan cayendo.
•
La matriz de leds que muestra en todo momento el estado de ocupación del área de juego
y que mantiene permanentemente actualizada la posición de la pieza bajo el control del
jugador.
•
El HW de audio (i.e. filtro y amplificador).
•
Las interrupciones temporizadas.
Los posibles casos de uso serían:
•
Cada vez que se produzca una interrupción temporizada, se modificarán los contadores
de tiempo. Si se está disputando una partida:
o Se resolverá la posible necesidad de gestionar los ajustes oportunos para la
reproducción de la siguiente nota de la melodía,
o Se resolverá la posible necesidad de modificar la excitación aplicada a la matriz
de leds conforme a la frecuencia de actualización elegida (i.e. refresco) de la
pantalla,
o Se resolverá la necesidad de modificar la posición de la pieza en movimiento,
reubicándola una línea más abajo, conforme al ritmo o velocidad de caída elegido.
Naturalmente, para actualizar dicha posición se tendrá en cuenta el estado de
ocupación de la pantalla. De esta forma, si no fuese posible prolongar la caída de
la pieza, se procedería bien a hacer aparecer una nueva pieza en la parte superior
de la pantalla (en caso de que hubiese espacio para ello), o bien simplemente a dar
por finalizado el juego.
o Los posibles rebotes mecánicos debidos a la pulsación de una tecla o a soltarla, se
suprimirán por SW. Si se pulsa una tecla una única vez, el sistema debe
interpretar una única pulsación sin que le afecten los posibles rebotes en la señal
que recibe del teclado.
o La duración de la pulsación de cada tecla (sea breve o sea larga) no debe dar lugar
a que se detecten varias pulsaciones de la misma tecla. El sistema debe ser capaz
de detectar pulsaciones lo suficientemente breves como para desplazar o rotar la
pieza de la manera deseada.
El sistema de menús sería, de manera orientativa, el siguiente:
•
Al comienzo, el sistema debe presentar al usuario un menú ofreciendo la posibilidad de
jugar con alguno de los 3 modos de dificultad disponibles. No se puede salir de este menú
mientras no se elija un nivel de dificultad correcto.
11
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
Antes de dar comienzo al juego se debe presentar un mensaje con el nivel de dificultad
elegido.
•
Una vez que el usuario ha elegido uno de los niveles de dificultad disponibles, se
esperará a que el usuario pulse la tecla A para comenzar a jugar. En ese momento se dará
comienzo al juego y se procederá a la reproducción de la melodía y a la visualización de
la primera pieza.
•
Una vez terminado el juego, se debe indicar el resultado de éste: el número de líneas
completadas.
•
Así mismo, se pondrá fin al proceso de reproducción de la melodía y el menú de
selección de nivel de dificultad deberá volver a aparecer para que el usuario pueda volver
a elegir otra.
•
Pulsar cualquier otra tecla distinta de las propuestas (más abajo indicadas) durante el
juego o durante el proceso de selección del nivel de dificultad no tendrá ningún efecto en
el sistema básico salvo que se desee implementar una determinada mejora con más teclas
útiles (e.g. pausar o cancelar el juego en curso).
•
Los mensajes se mostrarán en la pantalla del ordenador. Durante el juego propiamente
dicho, no se muestran mensajes por pantalla hasta que termina el juego y se muestran los
resultados finales.
•
Como los leds están organizados en forma de matriz con 12 entradas, se usarán 8
terminales para iluminar o no cada uno de los 8 leds que hay en una columna, y otros 4
para seleccionar qué columna iluminar. Para que no se perciba parpadeo, el sistema:
o iluminará los leds apropiados de la primera columna durante unos 5 ms,
o posteriormente, pasará a iluminar sucesivamente las siguientes columnas durante
el mismo periodo de tiempo,
o tras alcanzar e iluminar la última columna, volverá a la 1ª cíclicamente.
•
De esta manera, cada led se puede encender y apagar hasta 50 veces por segundo,
produciéndose la ilusión de que los leds de varias columnas están encendidos a la vez,
cuando realmente en cada instante de tiempo, sólo están siendo excitados los leds de una
columna.
Asignación estándar de teclas:
Tabla 2. Asignación estándar de teclas para el juego en el teclado matricial del LSED.
TECLA 1
TECLA 4
TECLA 7
TECLA A
Nivel 1
Nivel 2
Nivel 3
Comienzo del juego
12
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
3. Subsistema Hardware
Figura 3. Diagrama general de bloques del subsistema hardware completo.
3.1 Matriz de leds
Conceptualmente necesitamos una matriz de 4 columnas y 8 filas de leds, matriz que podremos
implementar siguiendo el esquema presentado en la Figura 4. Siguiendo dicho esquema, si
aplicamos 5 voltios a una columna y 0 voltios a las demás (usando un buffer 74HC244
conectamos las columnas al puerto de salidas digitales del entrenador), y si aplicamos 5 voltios a
las filas que no queramos iluminar, y 0 a las que deseemos iluminar (las conexiones entre el
puerto de salida y las filas requiere otro buffer y un conjunto de resistencias para que los leds
no consuman mucha corriente pero se iluminen bien), conseguiremos ir mostrando las piezas del
juego ocupando diferentes posiciones en pantalla según los movimientos que hayamos realizado
mediante el uso de las teclas. Los buffers tienen por objetivo no pedir mucha corriente a los puertos
del entrenador (sino a los 74HC244).
13
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Figura 4. Detalle del subsistema HW de visualización de la melodía (8 filas y 4 columnas).
Como posible mejora se prevé la posibilidad de diseñar un dispositivo de visualización más
elaborado que haga uso, por ejemplo, bien de un display LCD o bien de un conjunto de displays de
7 segmentos. En este último caso, podrían aprovecharse las conexiones internas del display de 7
segmentos para ahorrar conexiones horizontales, resultando además especialmente sencilla la
alineación de los leds. En ambos casos (i.e. uso de un LCD o de un conjunto de displays de 7
segmentos), el procedimiento necesario para poder representar las piezas por pantalla adquiere una
complejidad notable, motivo por el que esta mejora sería considerada como de dificultad alta.
3.2 Filtrado de la señal
En primer lugar la señal cuadrada generada por el MCF5272 se filtra para reducir sus armónicos.
Esta señal se genera a través de la salida TOUT0 del temporizador 0 (TIMER 0) que se corresponde
con el PIN 13 del conector de salidas digitales. Si se aplica esta señal directamente sobre un altavoz
podremos reconocer perfectamente la nota o melodía reproducida (aunque la percibiremos con una
fuerte distorsión).
La misión del filtro tiene como objetivo principal reducir el número de armónicos, reduciendo
también la sensación de distorsión de la nota reproducida. Este filtro será un filtro paso bajo con
frecuencia de corte superior o igual a 12KHz (para permitir al menos 2 armónicos de la nota con
mayor frecuencia: última nota de la octava 7).
En un principio podríamos pensar en generar una señal sinusoidal perfecta pero este tipo de señal
no simula correctamente el sonido producido por un instrumento, el cual tiene más riqueza
espectral. Por esta razón, colocaremos un filtro que reduzca los armónicos pero que mantenga al
14
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
menos los 3 primeros. En el apartado de mejoras se propondrá la generación de diferentes tipos de
onda para simular diferentes instrumentos.
Para la implementación de este filtro paso-bajo se propone un filtro de 2º orden Sallen-Key con
ganancia unidad, similares a los desarrollados en LCEL (consultar [12], apartado 5.7). Un aspecto
que debemos tener en cuenta en este caso es que la señal a filtrar es una señal digital entre 0 y 5
voltios, mientras el filtro lo alimentaremos entre –10 voltios y 10 voltios. Por esta razón es
necesario eliminar la componente continua utilizando una red R-C (en configuración filtro paso
alto) con valores de C y de R elevados de forma que la frecuencia de corte sea muy baja (de unos
pocos Hz). A la salida del filtro debemos tener una señal de igual o menor rango dinámico que a la
entrada.
3.3 Amplificador de potencia
La salida de los circuitos digitales (y de muchos amplificadores operacionales con los que se
construyen los filtros) tiene una limitación importante en relación con la corriente que pueden
ofrecer. En muchos casos, esta corriente no es suficiente para excitar unos altavoces. Por esta razón,
es necesario incluir un módulo de amplificación de potencia previo a los altavoces.
Para la implementación de este módulo se recomienda utilizar el amplificador de potencia
LM386 [13] utilizando alguno de los montajes que propone el fabricante (es necesario eliminar la
componente continua antes de amplificar). En la Figura 5 se muestra el montaje más sencillo.
Un aspecto importante que el alumno debe tener en cuenta es que este amplificador presenta una
ganancia entre 20 y 200. Por esta razón, se debe incluir una etapa de atenuación que reduzca el
margen dinámico de la señal. Al realizar el montaje se recomienda al alumno que consulte las hojas
de especificaciones del LM386 con el fin de ajustar correctamente los niveles de las señales y de la
alimentación. La impedancia del altavoz se puede modelar aproximadamente como una resistencia
de unos 10 ohmios.
Figura 5. Propuesta de montaje para la implementación del amplificador de potencia.
15
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
También es necesario recordar la importancia del filtrado de alimentación típico del LCEL,
apartado 5.10 de [14], especialmente cuando se conecta el amplificador de potencia, que puede
requerir incluso una alimentación independiente. Si no se hace, el filtro puede funcionar mal debido
al ruido que le entre por su alimentación.
Aunque la melodía se oiga razonablemente bien es importante comprobar con el osciloscopio el
correcto funcionamiento tanto del filtro paso-bajo como del amplificador de potencia. Cuando se
compruebe el funcionamiento del amplificador de potencia de forma aislada es importante probarlo
utilizando señales sinusoidales (obtenidas del generador de funciones) con el fin de detectar
posibles problemas de saturación.
3.4 Cascos o auriculares
Finalmente la reproducción de las melodías se realizará utilizando auriculares (nunca altavoces)
y con un volumen de reproducción bajo, sólo audible para las personas que tienen puesto el
auricular. El motivo es no incrementar innecesariamente el ruido del laboratorio, evitando molestar
al resto de compañeros.
3.5 Observaciones adicionales sobre el HW de entrada/salida
Es necesario recordar que los puertos de entrada y salida disponibles en la plataforma
ENT2004CF están formados por buffers digitales con resistencias de pull-down de 10 kilohmios. Si
no se tiene en cuenta este hecho, se podrían producir efectos de carga no deseados al conectar el
HW a la plataforma.
3.6 Alimentación de los subsistemas
Los subsistemas se alimentarán con tensiones simétricas o asimétricas, según convenga. Es muy
importante desacoplar las alimentaciones y alimentar en estrella; remitimos al alumno a la
referencia bibliográfica [5].
Si algún elemento puede demandar picos fuertes de corriente (por ejemplo, un amplificador de
potencia), puede ser muy importante filtrar de manera extraordinaria su alimentación para que estos
picos no afecten al resto de la circuitería (por ejemplo, un filtro de audio).
4. Subsistema digital basado en el MCF5272
Este subsistema lo forma la plataforma ENT2005CF cuya descripción se puede consultar en [3].
El manejo del entorno de desarrollo EDColdFire y las funciones de la TRAP #15 para comunicarse
con el PC son descritos detalladamente en esta referencia. Es imprescindible realizar los
principales tutoriales del EDColdFire que se proponen en las referencias [3][4] para aprender
el manejo de los principales recursos de la plataforma ENT2005CF que se usarán en este
sistema (http://lsed.die.upm.es).
16
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
5. Subsistema Software
Este subsistema lo forma el programa cargado en la plataforma ENT2004CF. Existen dos
documentos de dudas y preguntas frecuentes (una para ensamblador y otro para C) de gran utilidad
en la etapa inicial de toma de contacto y elaboración de los primeros programas [7][8].
5.1 Modelo de requisitos de SW
En esta asignatura, el análisis y el modelo de requisitos no son competencia exclusiva del
alumno, sino que son, parcialmente, información que se le proporciona para la realización de la
práctica. Supongamos que tenemos un cliente que desea que desarrollemos un prototipo de bajo
coste de un juego con las características mencionadas en el apartado 2.1. Tras diversas entrevistas
con este hipotético cliente, podríamos llegar a un ámbito del proyecto SW como el ya incluido
previamente en la descripción del apartado 2.2 “Objetivo general”.
5.2 Modelo de objetos orientativo
La labor de descubrir qué objetos o estructuras de datos son relevantes en nuestro proyecto es
sistematizable sólo hasta cierto punto. Tras un análisis de los requisitos recogidos en la sección 2
(especialmente de los sustantivos y de los adjetivos y verbos que pueden sustantivarse), se ha
determinado que los objetos principales pueden ser los siguientes:
•
Tecla: teclado, pedir, pulsación, dígitos, rebotes…
•
Estado: relacionado con palabras o términos como menús, niveles de dificultad,
comenzar, selección, escoger, aceptar,…
•
Piezas: forma, ancho, alto, posición…
•
Juego: movimientos, traslación, rotación, colisión…
•
Leds: columnas, filas, matriz de leds, iluminar, visualización de las piezas, parpadeo,
ocupación…
•
Relojes: retardos, tiempo real…
•
Melodía: onda cuadrada, HW, reproducir, ritmo, ralentizar, nota, nota anterior,
frecuencia, duración…
•
Resultados: juego, medir, número de líneas completadas, tiempo de juego, mostrar…
•
Pantalla: escribir, ventana de terminal, ver, mensajes…
•
Puertos: terminales digitales de salida, excitar…
5.2.1 Tecla
Representa cada símbolo pulsado por el usuario, tanto durante el juego como durante la
configuración.
17
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Deberá contar con métodos que permitan:
•
Inicializar convenientemente el teclado y el conjunto de variables necesarias para su
oportuna exploración.
•
Llevar a cabo la exploración del teclado y permitir la recuperación o lectura de las
diferentes pulsaciones de las teclas que lo componen.
Relaciones con otros objetos:
•
Juego: el objeto Tecla determina los movimientos de traslación o rotación requeridos por
el usuario para fijar la ubicación de las diferentes piezas.
•
Puertos: para detectar una tecla es necesario excitar adecuadamente algún bit o bits del
puerto de salida, y leer los bits adecuados del puerto de entrada.
•
Estado: las respuestas a los menús de este objeto se obtienen del objeto Tecla.
5.2.2 Estado
Objeto que representa las opciones escogidas por el usuario (i.e. nivel de dificultad
seleccionado), el estado en que se encuentra en todo momento nuestro sistema (i.e. si se está
jugando o simplemente configurando)...
Es un objeto activo con un menú asociado cuyo papel ha quedado claramente definido en los
casos de uso.
Tendrá métodos tales como Estado.inic() o Estado.menu().
Relaciones con otros objetos:
•
Tecla: las teclas pulsadas para el menú del objeto Estado son proporcionadas por el
objeto Tecla.
•
Melodía: en función del Estado, se reproduce (o no) la melodía.
•
Pantalla: los menús del objeto Estado se muestran en la Pantalla.
•
Leds: el estado de ocupación de la matriz de leds determinará el instante en que se decida
la finalización de la partida en curso (i.e. que se agote el espacio disponible en la matriz
para la disposición de más piezas).
5.2.3 Piezas
Este objeto debe contener la información característica de cada uno de los tipos de pieza que
pueden aparecer durante el juego: la anchura, la altura, la orientación y la ocupación del área de
juego de cada pieza.
Deberá contar con métodos que permitan:
18
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
Inicializar las estructuras en memoria necesarias para modelar los diferentes tipos de
pieza considerados en el juego, incluyendo todas las características anteriormente
mencionadas.
•
Crear o añadir una nueva pieza al juego de alguno de los tipos anteriormente definidos.
•
Recuperar respectivamente los valores vigentes para las diferentes propiedades de una
pieza: la anchura, la altura, la rotación y, especialmente, la ubicación de la pieza dentro
del área de juego (i.e. en la matriz de leds).
Relaciones con otros objetos:
•
Juego: el objeto Juego recuperará del objeto Piezas toda la información necesaria para
resolver correctamente, conforme a las reglas de juego, cada uno de los posibles
movimientos (i.e. abajo, izquierda, derecha, rotación) a los que se pueda ver sometida
una pieza. Naturalmente, y con motivo de dichos movimientos, Juego actualizará
pertinentemente la información de posición y orientación de la pieza controlada por el
jugador.
•
Leds: las piezas deben visualizarse en la matriz de leds.
Figura 6. Tipos de pieza (Fuente: Sitio web oficial Tetris, www.tetris.com).
5.2.4 Juego
El sistema debe contar necesariamente con un objeto que defina en todo momento las
características generales del juego (e.g. el nivel, la pieza actual, la pieza siguiente, el tiempo
máximo de permanencia de una pieza en una determinada línea, etc.) y que garantice la integridad
del juego conforme al conjunto de reglas o restricciones básicas definidas para éste.
Deberá contar con métodos que permitan:
•
Llevar a cabo la oportuna inicialización de toda variable o estructura de datos que resulte
necesaria para el desarrollo del juego.
•
Ejecutar los diferentes movimientos contemplados para cada pieza, véase tanto los de
traslación: hacia la izquierda, hacia abajo o hacia la derecha, como los de rotación (la
rotación se realizará siempre en sentido anti-horario y a intervalos regulares de 90º).
•
Garantizar la viabilidad de dichos movimientos mediante la comprobación de que la
nueva posición de la correspondiente pieza no suponga que ésta rebase o exceda los
límites definidos para el área de juego o que tenga lugar una colisión con cualquier otra
pieza anteriormente ubicada en esa misma posición.
19
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Relaciones con otros objetos:
•
Piezas: este objeto irá proporcionando nuevas piezas que incorporar al juego cuando sea
necesario. Así mismo, Juego recibirá de éste toda la información correspondiente tanto a
la pieza actual (i.e. en movimiento bajo el control del jugador) como a la siguiente (que
entrará en juego inmediatamente después de la colocación de la primera).
•
Relojes: es el objeto que determina el momento en que debe actualizarse la posición de la
pieza actualmente en juego con motivo de la caída de la misma.
•
Leds: el objeto Leds debe proporcionar al objeto Juego información acerca de la
ocupación de las distintas posiciones en el área de juego, así como también, de las
dimensiones de esta última para poder determinar la viabilidad de los movimientos de
traslación o rotación de las Piezas.
5.2.5 Leds
Este objeto permite mostrar las piezas del juego en una matriz de leds. Para ello debe contener
información acerca de las dimensiones de la matriz y de la ocupación de las distintas posiciones que
la conforman (correspondiente al encendido/apagado de cada uno de los leds).
Como la matriz en cada momento sólo puede tener iluminados los leds de una de sus 4
columnas, el objeto leds debe encargarse de producir la ilusión de que las piezas caen y de hacer un
barrido que (cambiando la columna iluminada cada 5 ms.) produzca la ilusión óptica de que todas
las columnas están iluminadas a la vez).
Deberá contar con métodos que permitan:
•
Inicializar convenientemente la estructura de datos en memoria que permita representar el
estado de ocupación de todas y cada una de las posiciones que componen el área de
juego, estado que a su vez determinará la situación de encendido o apagado de los leds
correspondientes.
•
Pintar cualquiera de las piezas definidas en una posición determinada dentro del área de
juego.
•
Borrar del área de juego una pieza concreta.
•
Borrar el área de juego al completo.
•
Eliminar del área de juego las líneas que estén completas (i.e. fila) y actualizarla
consecuentemente.
Relaciones con otros objetos:
•
Piezas: el objeto Piezas debe proporcionar la información correspondiente a la propia
pieza que se desee pintar o borrar: la orientación, la anchura, la altura y la matriz de
ocupación asociada.
•
Estado: que indica cuándo comenzar a visualizar.
•
Relojes: que proporciona la base de tiempos.
20
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
5.2.6 Relojes
En los objetos anteriormente descritos es necesario contar tiempos para controlar el ritmo de
caída de las piezas, la duración de los posibles rebotes de las teclas, la duración de cada una de las
etapas que permiten el barrido de la matriz de leds, la duración de las notas que componen la
melodía de juego, etc. Para ello se necesitarán dos temporizadores que generen interrupciones
periódicas (al menos 1000 por segundo, suficiente para medir los tiempos con una precisión
razonable) y un conjunto de contadores de tiempo que formarán el objeto relojes.
Tendrá métodos tales como: Relojes.inic() o Relojes.actualizar().
Relaciones con otros objetos:
•
Melodía: para poder reproducir las distintas notas que componen la melodía, se generará
para cada una de ellas una onda cuadrada con la frecuencia requerida y durante tanto
tiempo como corresponda según la duración de la nota, tiempo que podrá medirse
empleando el objeto relojes.
•
Leds: la visualización se realiza al ritmo de la melodía y va a ser necesario realizar un
barrido periódico de las columnas de la matriz de leds.
5.2.7 Melodía
En nuestro programa debemos disponer de toda la información relativa a la melodía propuesta
para su reproducción en esta práctica: frecuencia de cada nota en Herzios, duración de cada nota en
milisegundos, nota actual, si la melodía ha terminado...
Los dos primeros datos son constantes, no deben ser modificados a lo largo del programa.
Deberá contar con métodos que permitan:
•
Configurar adecuadamente la interrupción asociada al proceso de reproducción.
•
Inicializar el conjunto de variables y estructuras de datos en memoria necesarias para la
oportuna gestión de dicha reproducción.
•
Arrancar el temporizador elegido para la generación de una onda cuadrada de una
determinada frecuencia.
•
Detener ese mismo temporizador en el momento en que se agote la duración de cada una
de las diferentes notas.
Relaciones con otros objetos:
•
Estado: que determina cuándo debe comenzar la reproducción de la melodía.
•
Relojes: que determina cuándo se debe proceder a la reproducción de la siguiente nota.
21
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Figura 7. Diagrama de objetos: arquitectura software.
5.2.8 Resultados
Este objeto contiene los datos importantes en relación al resultado de la última partida disputada:
el número de líneas completadas. Esta información debe ser enviada a la pantalla para que se pueda
leer.
Tendrá métodos tales como Resultados.inic(), Resultados.Actualizar () o Resultados.mostrar().
Relaciones con otros objetos:
•
Estado: sólo se muestran resultados tras la finalización de una partida.
•
Pantalla: para mostrar los resultados.
5.2.9 Pantalla
Este objeto permite mostrar mensajes en la pantalla de terminal del EDColdFire, como los
mensajes de los menús o los del resultado del juego.
En nuestro caso, la implementación puede simplemente encapsular el manejo de la TRAP #15 (o
de las funciones output() y outNum() en C).
Relaciones con otros objetos:
•
Estado: en la pantalla se muestran los menús del objeto Estado.
•
Resultados: en la pantalla se muestran los resultados.
22
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
5.2.10
Puerto
Este objeto permite coordinar el manejo del puerto de salida (tanto en C como en ensamblador)
al que pueden acceder varios procesos. Los objetos leds y tecla deben usar los servicios del objeto
puerto para evitar que un objeto modifique los bits del otro.
Tendrá
métodos
tales
como
Puerto.inic(),
Puerto.columnaLedsSeleccionar() o Puerto.filaLedsIluminar().
Puerto.tecladoColumnaExcitar(),
Relaciones con otros objetos:
•
Tecla: para detectar una tecla es necesario excitar adecuadamente el puerto de salida.
•
Leds: para encender o apagar los leds es necesario excitar adecuadamente el puerto de
salida. El objeto Leds proporciona la información correspondiente a la columna cuyos
leds es necesario encender o apagar según el estado de ocupación de dicha columna en la
matriz.
5.2.11
Rutinas o métodos generales de los objetos de un sistema
Todos los objetos (o estructuras de datos) pueden tener asociadas al menos 2 ó 3 funciones (o
métodos) generales que los manejan:
•
Inicializar (inic): asigna valores iniciales a las propiedades de un objeto o estructura de
datos. Como parte de la simulación de un programa en C, suele abrir un fichero de
depuración donde se escribirán todos los eventos y valores del objeto a lo largo del
tiempo, y que permite analizar detalladamente su funcionamiento a posteriori.
•
Re-inicializar (reset): vuelve a darle valores a las propiedades (aunque, para la mayoría
de los objetos, pueden coincidir con los valores de inicialización).
•
Finalizar (fin): en el caso que nos ocupa, su existencia no tiene sentido, porque los
objetos no desaparecen hasta que termina el propio sistema, y no son objetos persistentes
cuyas propiedades haya que guardar para inicializar posteriores ejecuciones del sistema.
5.3 Modelo de diseño
En el modelo de diseño adaptamos nuestro modelo de objetos para tener en cuenta:
•
Los requisitos temporales capturados en el modelo de requisitos.
•
El HW de que disponemos (su velocidad, su arquitectura...).
•
El SW previo que deseamos reutilizar (la trap #15...).
5.3.1 Arquitectura del sistema SW
La arquitectura de un sistema es el esqueleto o el esquema sobre el que se asienta un sistema y
que varía muy poco a lo largo del tiempo, aunque permite que el resto de los módulos no
arquitecturales evolucionen. Establece la división del sistema en subsistemas y regula sus
relaciones, su ubicación y su sincronismo (un subsistema es un objeto o conjunto de objetos con una
23
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
interfaz definida y reducida, que pueden ser tratados como una unidad de cara al resto del sistema).
Es el primer elemento de todo buen diseño, y debe estar presente desde el primer prototipo. Es
frecuente comenzar un sistema diseñando e implementando un primer prototipo que recoge la
arquitectura propuesta para el sistema completo, aunque los subsistemas incluidos carezcan de
funcionalidad (o dispongan de una funcionalidad elemental muy alejada de la finalmente necesaria).
Continuando con el ejemplo que estamos comentando, nuestro análisis de los principales objetos
nos da casi directamente la arquitectura, aunque en un sistema de unas ciertas dimensiones esto no
ocurre, siendo necesario emplear los diversos criterios de agrupamiento antes mencionados. Sin
embargo, no es extraño que, por cada una de las conexiones del sistema con los agentes exteriores,
exista un subsistema interfaz para esa conexión, de tal manera que los procesadores queden
independizados del modo de intercambiar datos con el exterior (lo cual facilita su simulación e
incrementa su portabilidad, por ejemplo).
La arquitectura debe ser capaz de soportar:
•
Los requisitos de diseño impuestos por el cliente: como en nuestro caso el uso de 4
teclas, de visualizadores matriciales, de reproducir una melodía durante el juego, etc.
•
Los requisitos impuestos por el HW: por ejemplo, el prototipo que vamos a diseñar
utilizará al menos 1 temporizador de MCF5272 para generar interrupciones periódicas. El
puerto de entradas digitales será empleado para leer la tecla pulsada. El puerto de salidas
digitales será utilizado para 2 objetivos: interfaz con el teclado (excitar la fila o columna
que deseamos leer) e iluminar los leds de la matriz de visualización del juego. Como los
puertos de salida son de sólo escritura, habrá que coordinar el uso que las rutinas de cada
objetivo hacen del puerto.
•
El SW disponible previamente (middleware): en nuestro caso el manejo de la pantalla
se debe hacer a través de la Trap #15, a fin de no tener que reprogramar la comunicación
y perder un tiempo precioso. Para el manejo del teclado y los temporizadores, es
imprescindible consultar los tutoriales sobre el teclado y la placa TL04, y sobre las
interrupciones temporizadas, y emplear las funciones que allí se nos proporcionan.
5.3.2 Modelo dinámico orientativo
Para describir la evolución de los objetos o los subsistemas a lo largo del tiempo y en función de
los eventos producidos, se deben emplear diagramas de transición de estados. Un estado de un
objeto se asocia a un valor o combinación de valores de sus propiedades, propiedades que son
variables, hecho particularmente relevante a la hora de describir su comportamiento dinámico a lo
largo del tiempo. Las transiciones entre estados son resultado de la aparición de eventos internos
(un cambio en un objeto puede generar un cambio en ese objeto o en otro) o externos (pulsar una
tecla o producirse una interrupción), que provocan además la ejecución de una o varias funciones
del objeto. Obsérvese que el modelo dinámico forma parte del diseño, dado que se encarga de la
temporización y permite articular una posible solución al problema planteado.
Objetos como Tecla, Melodía, Juego, Puerto, Leds o Relojes, tienen una dinámica especial
regida por máquinas de estados que a continuación describiremos.
24
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
5.3.2.1 Modelo dinámico orientativo del objeto Tecla
•
Espera y Detección: a priori, un teclado matricial como el de la placa TL04 requiere un
barrido como el que se describe en SEDG o en el tutorial del teclado. Sin embargo, si
únicamente se emplea las teclas ‘1’, ‘4’ , ‘7’ y ‘A’, que están conectadas a la misma
columna y un mismo terminal de salida (el bit 0 del puerto de salida), es posible no
realizar el barrido, sino excitar esa columna (en la inicialización del objeto Tecla) y leer
el puerto de entrada (conectado a las filas del teclado matricial como se muestra en la
Figura 2) para ver si alguna de esas teclas ha sido pulsada. Se debe registrar la tecla
pulsada y el instante de tiempo de la pulsación.
•
Antirrebotes al pulsar: si se ha detectado una tecla, hay que registrar en qué instante de
tiempo se produjo la pulsación (teniendo en cuenta un contador asociado al teclado en el
objeto Relojes) y en qué tecla, y esperar un cierto tiempo por si hubiese rebotes
mecánicos al pulsar (empleando un contador asociado a los rebotes en el objeto relojes).
•
Esperar que se suelte la tecla pulsada: una vez pasado este tiempo, hay que esperar
hasta que el usuario suelte la tecla (para evitar que una pulsación larga sea interpretada
como varias pulsaciones).
•
Antirrebotes al soltar: una vez se ha soltado la tecla por primera vez, puede que haya
que esperar un cierto tiempo por si hubiese rebotes mecánicos al soltar la tecla
(empleando un contador asociado a los rebotes en el objeto relojes).
5.3.2.2 Modelo dinámico orientativo del objeto Puerto
Este objeto, aparentemente sencillo, se ve complicado por el hecho de que los puertos del
entrenador son unidireccionales, por lo que el objeto debe guardar el último valor enviado al puerto
(y por lo tanto presente en el mismo) y cuando necesite cambiar un bit, actualizar la variable
guardada y volverla a enviar. Además, cuando es llamado desde el programa principal, podría tener
que habilitar y deshabilitar las interrupciones para evitar que el puerto (o la variable) sean
modificados a la vez por los dos procesos.
5.3.2.3 Modelo dinámico orientativo del objeto Relojes
La responsabilidad de incrementar o decrementar este objeto u objetos de tipo contador correrá a
cargo de las interrupciones periódicas. Concretamente, en nuestro sistema contaremos con dos
interrupciones de distinta prioridad, tal y como veremos posteriormente. El comportamiento del
objeto es muy simple: se incrementa o decrementa en cada interrupción, y es consultado, por
ejemplo, por los procesos asociados a los objetos Tecla y Melodía, a fin de poder realizar retardos o
esperar el tiempo restante para la nota actual, respectivamente. Así por ejemplo, si se implementa
una estrategia antirrebotes por SW, este reloj o relojes pueden servir para no leer el teclado durante
el tiempo estimado de rebotes.
Si la frecuencia de interrupciones es de 1 KHz, podríamos contar tiempos en milisegundos sin
más que contar el número de interrupciones de este temporizador. Por esta razón se expresará la
duración de cada nota en milisegundos. Además el milisegundo es una unidad suficientemente
pequeña como para garantizar una resolución aceptable tanto para la adecuada excitación de la
matriz de leds como para la reproducción de las notas musicales.
25
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Figura 8. Posición de las diferentes piezas en la matriz de leds.
5.3.2.4 Modelo dinámico orientativo del objeto Piezas
Desde el punto de vista semántico toda pieza puede caracterizarse por dos propiedades
fundamentales: su posición y su forma. Ambas propiedades son claramente de naturaleza dinámica
toda vez que sus respectivos valores pueden ir variando a lo largo del juego. Efectivamente, tanto la
posición como la forma de una determinada pieza deberán ser actualizadas convenientemente tan
pronto se produzca un movimiento de traslación o de rotación, respectivamente.
Para poder articular la información relativa a la posición de una determinada pieza (resultado de
los diferentes movimientos de traslación realizados), y dado el modelo matricial propuesto para el
área de juego (construida como una matriz de leds), lo más sencillo es emplear un sistema de
coordenadas cartesianas (x, y) que permita hacer referencia a cualquiera de las posiciones del
mismo. Por simplicidad, podemos hacer coincidir nuestro origen de coordenadas con cualquiera de
las esquinas del área de juego. En particular, en la Figura 8, lo hemos hecho coincidir con la esquina
superior izquierda. Así mismo, hemos representado el área de juego con un posible estado de
ocupación en el que hemos incluido, a modo de ejemplo, una pieza de cada uno de los siete tipos
contemplados en el juego.
26
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Para cada pieza, hemos destacado la información de posición correspondiente respecto a nuestro
origen de coordenadas. De este modo, podemos comprobar, por ejemplo, que el tetromino o pieza
de mayor longitud (ver esquina inferior derecha) ocupa la posición (3, 4) o que el tetromino en
forma de T ocupa la posición (1, 5) dentro de la matriz de leds. Para poder entender éste último
caso, en el que las coordenadas de posición de la pieza corresponden a un led que no forma parte de
la pieza en sí, es preciso detallar el modelo de pieza empleado.
De igual modo que ocurre con el área de juego, vamos a modelar cada pieza como una matriz, la
forma más simple de representarlas dada la naturaleza matricial del juego. Este modelo matricial de
de pieza, para el que hemos incluido la Figura 9 a modo de ejemplo, queda definido por la altura y
la anchura de la pieza que delimitarán a su vez el número de filas y columnas respectivamente de la
matriz asociada (e.g. 3 filas y 2 columnas para la pieza en forma de T asumiendo la orientación en
la que dicha pieza ha sido representada en la figura).
Adicionalmente, dicha matriz nos permitirá representar el estado de cada uno de los leds
comprendidos dentro del área de ocupación de la pieza. Concretamente, modelaremos cada una de
las diferentes posiciones dentro de la matriz por medio de una variable binaria cuyo valor 1 o 0
representará respectivamente el encendido o apagado del led correspondiente.
En este sentido, y a la vista del ejemplo presentado, es preciso destacar el empleo de un nuevo
sistema de coordenadas auxiliar específico para cada pieza, cuyo origen, por coherencia, hemos
hecho coincidir nuevamente con la esquina superior izquierda de la matriz y, por tanto, con las
coordenadas de posición de la pieza dentro del área de juego (e.g. la posición (1, 5), columna 1 y
fila 5, en la matriz de leds del tetromino en forma de T corresponde a la posición (0, 0) de la matriz
o área de ocupación asociada a dicha pieza). De este modo podremos referenciar y recorrer
fácilmente las diferentes posiciones del área de ocupación de la pieza. Tal y como puede
observarse, todas las coordenadas incluidas en la figura están referidas a dicho origen de
coordenadas.
Figura 9. Modelo matricial de pieza: área de ocupación de la pieza.
27
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Naturalmente, cada matriz debe tener unas dimensiones inferiores al propio área de juego (i.e.
matriz de leds) que aseguren la correcta disposición en el mismo de la pieza más grande que
queramos definir (al menos cuando el tablero se encuentre vacío). No obstante, tal y como puede
comprobarse, este requisito no supondrá inconveniente alguno en el caso que nos ocupa, dadas las
dimensiones de la pieza más grande y de la matriz de leds. Igualmente, y por simplicidad,
podremos definir todas las matrices de ocupación correspondientes a los diferentes tipos de
pieza con el mismo tamaño, NxN, siendo N la mayor altura, o anchura, de cualquiera de las piezas
consideradas (e.g. 4x4).
En relación al caso particular de los movimientos de rotación, es preciso destacar dos decisiones
de diseño especialmente importantes desde el punto de vista de la implementación de nuestro
sistema:
•
En primer lugar asumiremos que ningún movimiento de rotación afectará en modo
alguno a la posición de la pieza.
•
En segundo lugar, extenderemos el modelo matricial de pieza para dar cabida a las
diferentes formas (i.e. rotaciones) que una misma pieza podrá presentar dependiendo del
giro o de la orientación de la misma con respecto a una orientación de referencia y a la
base del área de juego (i.e. eje x o de abcisas).
De este modo, para ejecutar la rotación de una determinada pieza simplemente será necesario
llevar a cabo la oportuna actualización de la matriz de ocupación de la pieza encendiendo y
apagando los leds correspondientes según la rotación elegida. En la Figura 10 hemos presentado un
posible modelo con las sucesivas rotaciones para una de las piezas en forma de J. Una
implementación bastante sencilla del modelo de rotaciones pasa por definir 4 matrices de
ocupación para cada pieza, una por cada una de las posibles rotaciones que puede adoptar cada
pieza. De ese modo, cada movimiento de rotación simplemente supone elegir en cada caso la matriz
correspondiente a la rotación escogida.
Nótese que para algunas piezas el número de rotaciones o matrices necesarias puede ser inferior,
como ocurre para la cuadrada cuyas sucesivas rotaciones no alteran la forma de la pieza (o cuyas 4
matrices de rotación son exactamente iguales, según se mire). En cualquier caso este hecho no debe
afectar al diseño toda vez que la implementación resulta más sencilla considerando que disponemos
de 4 matrices para cada pieza (a pesar de que algunas puedan ser exactamente iguales).
5.3.2.5 Modelo dinámico orientativo del objeto Leds
Asumiendo que será responsabilidad exclusiva del objeto Juego la oportuna actualización
de la matriz asociada al área de juego, el modelo dinámico del objeto Leds resulta bastante
sencillo. Este modelo está basado en la lectura o consulta de dicha matriz con objeto de aplicar
sucesivamente el barrido de excitaciones necesario para que cada columna de leds pueda
encenderse y apagarse hasta 50 veces por segundo, produciéndose la ilusión de que los leds de
varias columnas están encendidos a la vez, cuando realmente en cada instante de tiempo, sólo están
siendo excitados los leds de una determinada columna.
28
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
x
x
y
1(0,0)
1(1,0)
0(2,0)
0(3,0)
1(0,0)
0(1,0)
0(2,0)
0(3,0)
1(0,1)
0(1,1)
0(2,1)
0(3,1)
1(0,1)
1(1,1)
1(2,1)
0(3,1)
1(0,2)
0(1,2)
0(2,2)
0(3,2)
0(0,2)
0(1,2)
0(2,2)
0(3,2)
0(0,3)
0(1,3)
0(2,3)
0(3,3)
0(0,3)
0(1,3)
0(2,3)
0(3,3)
y
a) Rotación 1.
b) Rotación 2.
x
y
x
0(0,0)
1(1,0)
0(2,0)
0(3,0)
1(0,0)
1(1,0)
1(2,0)
0(3,0)
0(0,1)
1(1,1)
0(2,1)
0(3,1)
0(0,1)
0(1,1)
1(2,1)
0(3,1)
1(0,2)
1(1,2)
0(2,2)
0(3,2)
0(0,2)
0(1,2)
0(2,2)
0(3,2)
0(0,3)
0(1,3)
0(2,3)
0(3,3)
0(0,3)
0(1,3)
0(2,3)
0(3,3)
c) Rotación 3.
y
d) Rotación 4.
Figura 10. Modelo de rotaciones para las piezas.
En particular, y mientras dure la partida, será necesario recorrer cíclicamente un autómata en
anillo de 4 estados (4 es el número de columnas de leds). Cada columna estará iluminada durante 5
ms y a continuación se pasará a iluminar la siguiente columna. Una vez finalizado el periodo de
excitación correspondiente a la última columna daremos comienzo nuevamente a un nuevo periodo
de excitación de la primera. Será el contenido de la matriz asociada al área de juego el que
determinará el conjunto de leds que es preciso iluminar en cada momento.
En la Figura 11 hemos incluido a modo de ejemplo el esquema de excitaciones correspondiente a
cada una de las etapas o estados del barrido necesario para refrescar la matriz de leds. En este
ejemplo hemos asumido el mismo estado de ocupación de la matriz presentado anteriormente.
El proceso a seguir para cada una de las 4 columnas puede resumirse de la siguiente manera:
•
recorreremos la columna de la matriz que estemos procesando (i.e. x), aquella que sea
objeto de la excitación, comprobando las posiciones correspondientes a las diferentes
filas (i.e. (x, 1), (x, 2),…),
•
sólo en caso de que la posición (x, y) contenga un valor 1 significará que debemos
iluminar el led asociado a la misma.
29
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
a) Excitación de la primera columna.
b) Excitación de la segunda columna.
c) Excitación de la tercera columna.
d) Excitación de la cuarta columna.
Figura 11. Refresco de la matriz de leds.
30
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
De este modo, podemos comprobar cómo para la excitación de la primera columna en el
ejemplo, cuya duración será de exactamente 5 ms, solamente es preciso excitar o iluminar los leds
ubicados en las filas F3, F4, F6, F7, y F8 (o lo que es lo mismo, los leds ubicados en las posiciones (0,
2), (0, 3), (0, 5), (0, 6) y (0, 7) de la matriz empleando nuestro sistema de coordenadas).
5.3.2.6 Modelo dinámico orientativo del objeto Juego
La función principal del presente objeto es aplicar en todo momento las reglas de juego ante los
sucesivos movimientos de piezas llevados a cabo por el jugador. Así mismo, será igualmente el que
decida acerca de la necesidad de añadir una nueva pieza al juego o de dar éste por finalizado.
Para la adecuada gestión de cualquier movimiento que pueda experimentar una determinada
pieza, resulta indispensable introducir el concepto de “colisión”.
5.3.2.6.1
¿Qué es una colisión?
Asumiremos que se produce una colisión toda vez que, bien como consecuencia de la propia
caída de la pieza o bien al realizar algún movimiento de traslación o rotación de la misma:
•
dicha pieza adquiera una posición que exceda o rebase los límites definidos para el área
de juego (i.e. colisión con los límites del área de juego).
•
o que la pieza adquiera una posición que ya estuviera anteriormente ocupada por otra
pieza (i.e. colisión con otras piezas).
5.3.2.6.2
¿Cómo gestionamos un movimiento?
La clave de cualquier movimiento, ya sea de traslación o rotación, a la derecha o a la izquierda, e
incluso de la propia caída de la pieza, está en la necesaria comprobación de su viabilidad,
comprobación que debe realizarse previamente a la ejecución del mismo para evitar así las
mencionadas colisiones. Desde este punto vista, el protocolo o secuencia de acciones necesaria para
la gestión de todo movimiento de pieza puede resumirse fácilmente de la siguiente manera:
•
Asumiendo que el objeto Teclas ya nos ha proporcionado información acerca del
movimiento específico solicitado por el jugador, en primer lugar realizaremos una copia
de la pieza que es objeto del movimiento. Para mayor claridad nos referiremos a dicha
pieza como piezaActual, y a la copia como piezaAuxiliar. Un posible prototipo de
función que nos permitiese realizar tal copia podría tener el siguiente aspecto:
CopiarPiezaTetris (Juego->piezaActual, &(Juego->piezaAuxiliar));
•
A continuación, podemos proceder a borrar piezaActual del área de juego actualizando
convenientemente la matriz asociada (i.e. apagando los leds correspondientes, es decir,
escribiendo un 0 en las posiciones ocupadas por la pieza). Este borrado podría encontrar
su equivalente en la supuesta acción de levantar la pieza del tablero de juego (con el
objetivo final de probar una nueva ubicación para la misma). Un posible prototipo de
función que nos permitiese realizar tal borrado podría tener el siguiente aspecto:
BorrarPiezaTetris (Juego->piezaActual, &Leds->matrizAreaJuego);
31
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
Acto seguido actualizaremos las coordenadas de posición de la copia piezaAuxiliar según
el movimiento solicitado, movimiento que en caso de producirse, por ejemplo, hacia la
derecha podría expresarse del siguiente modo:
Juego->piezaAuxiliar.posicion_X = Juego->piezaAuxiliar.posicion_X + 1;
•
Una vez actualizada la posición de piezaAuxiliar es el momento de comprobar si la nueva
ubicación de la pieza da lugar a colisión alguna. Si el resultado de la comprobación es
negativo daremos el movimiento por válido y sólo nos restará actualizar las nuevas
coordenadas de posición de piezaActual. Esta copia podría encontrar su equivalente en la
supuesta acción de colocar la pieza en la ubicación ensayada dentro del tablero de juego.
En caso de producirse una colisión, asumiremos que el movimiento no puede llevarse a
cabo, y por tanto que la pieza debe permanecer en su posición original. Para conseguirlo
simplemente bastará con volver a pintar piezaActual, tal y como veremos en el siguiente
paso. Ambas acciones, la comprobación y la posible copia, podrían tener el siguiente
aspecto:
if (posibleMoverPieza (Juego->piezaAuxiliar, Leds->matrizAreaJuego))
{
CopiarPiezaTetris (Juego->piezaAuxiliar, &(Juego->piezaActual));
}
•
Finalmente, tanto si el movimiento resulta posible como si no, el último paso consistirá
en volver a pintar la pieza (i.e. encendiendo los leds correspondientes, es decir,
escribiendo un 1 en las posiciones, en este caso definitivas, ocupadas por la pieza). Un
posible prototipo de función que nos permitiese realizar tal borrado podría tener el
siguiente aspecto:
PintarPiezaTetris (Juego->piezaActual, &Leds->matrizAreaJuego);
5.3.2.6.3
¿Cuándo añadir una nueva pieza o dar por finalizado el juego?
En este sentido resultan particularmente importantes las colisiones que puedan producirse ante
un eventual movimiento hacia abajo de la pieza (provocado por el usuario o simplemente debido a
la propia caída de las piezas).
En caso de que no resulte posible mover hacia bajo la pieza (por producirse una colisión)
comprobaremos la posición de la pieza. Si la coordenada y correspondiente resulta negativa,
condición que coincidiría con una situación en la que el espacio disponible en el área de juego se ha
agotado, daremos el juego por terminado. Para poder articular este procedimiento es fundamental la
adecuada inicialización de la información de posición para cada una de las piezas que entre en
juego. Una posible inicialización consistiría en asignar unas coordenadas iniciales (0, altura de la
pieza para la forma u orientación por defecto + 1).
Por el contrario, si no fuese posible mover hacia abajo la pieza (debido a una colisión bien con el
fondo o límite inferior del área de juego, o bien con las últimas piezas colocadas sobre la misma)
pero la coordenada y tuviese un valor comprendido dentro del área de juego, consolidaríamos la
pieza en dicha posición y procederíamos sucesivamente a comprobar si es preciso eliminar alguna
línea que haya podido completarse y a añadir una nueva pieza al juego.
32
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
La decisión en cuanto a qué nueva pieza debe incorporarse al juego podría tener un carácter
aleatorio (como ocurre con la versión real del juego). No obstante, esta podrá simplificarse de tal
modo que simplemente suponga recorrer circularmente el array o estructura de datos en memoria
que contenga la información de los diferentes tipos de pieza incorporando sucesivamente una pieza
distinta en cada ocasión.
5.3.2.6.4
¿Cómo implementar el movimiento de caída de las piezas?
A diferencia del resto de movimientos, la caída de las piezas no está controlada por el jugador.
Ésta se produce de forma cíclica, discontinua y a intervalos regulares de tiempo (i.e. ritmo de caída
de las piezas o tiempo límite que permanece una pieza, en ausencia de movimientos provocados por
el jugador, en una misma línea antes de pasar a la siguiente) cuya oportuna medición correrá a cargo
de una de las interrupciones periódicas habilitadas en nuestro sistema (i.e. objeto Relojes).
Cada vez que la pieza en movimiento agote el tiempo máximo que puede permanecer en una
misma línea (un valor razonable para el nivel de menor dificultad puede estar alrededor de 1 ó 2
segundos), deberá actualizarse la posición de la pieza ubicándola en la línea siguiente. Por lo tanto,
nos encontraremos ante un caso particular de movimiento hacia abajo cuyo detonante será el
timeout identificado por el objeto Relojes en lugar de la pulsación de la tecla correspondiente. Por
lo demás, la gestión de dicho movimiento deberá realizarse exactamente en los mismos términos
que hemos mencionado anteriormente en la sección 5.3.2.7.2 de este mismo documento.
5.3.2.7 Modelo dinámico orientativo del objeto Melodía
Este objeto tiene almacenada la melodía que debe reproducirse durante el juego. Al dar
comienzo el juego, se debe comenzar a reproducir la primera nota de la melodía (i.e. onda cuadrada
cuya frecuencia será igual al primer valor especificado en la secuencia de frecuencias definida para
la melodía). Dicha nota se reproducirá durante el tiempo especificado por su duración
correspondiente (información especificada en la secuencia de duraciones). Cuando el tiempo de
reproducción de dicha nota llegue al tiempo especificado por la melodía, la nota actualmente
reproducida pasará a ser la siguiente nota de la secuencia de notas a reproducir.
Cuando se haya acabado de reproducir la última nota, se deberán llevar a cabo las gestiones
oportunas para poder reproducir nuevamente la melodía desde el comienzo. Así mismo, una vez
finalizado el juego deberá finalizarse igualmente la reproducción de la melodía.
5.3.3 Estructura obligatoria de procesos
Frecuentemente, los sistemas electrónicos digitales precisan realizar diversas acciones de una
manera paralela (concurrente en varios procesadores) o aparentemente paralela (ambas acciones se
ejecutan entrelazadamente, produciéndose la apariencia de paralelismo si la frecuencia de
conmutación entre ambas es elevada). Son los denominados procesos. La creación, ejecución,
sincronización y destrucción entre procesos suele ser facilitada por el sistema operativo a través de
diversas primitivas. Pero incluso en ese caso, el diseñador debe definir qué tareas o rutinas serán
concurrentes, elegir los mecanismos de comunicación entre ellas, los tiempos de vida, etc.
En el LSED no disponemos de un gran sistema operativo en nuestra placa de desarrollo, pero
podemos definir varios procesos por medio de interrupciones periódicas, interrupciones externas y
el programa principal.
33
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
En la Figura 12 se muestra el esquema de procesos propuesto para esta práctica. Dicho esquema
comprende 3 procesos: el programa principal y dos interrupciones periódicas. Este esquema de
procesos es obligatorio.
Se puede observar que las funciones asociadas a un mismo objeto no se ejecutan necesariamente
en un mismo proceso. Sobre los mecanismos de sincronización en el LSED, recomendamos la
lectura del apartado 4.1.6 “Desarrollo de software de tiempo real” de [3]. Como en nuestro caso las
interrupciones periódicas pueden interrumpir la ejecución del programa principal en instantes de
tiempo que resultan imprevisibles cuando se escribe el código, si el programa principal necesita
modificar un objeto compartido, procederá a deshabilitar las interrupciones, realizar la
modificación y volver a habilitar las interrupciones. Todo este conjunto de operaciones puede
encapsularse en el objeto puerto. Como el programa principal no puede interrumpir a las propias
interrupciones, estas últimas no necesitan realizar ninguna operación especial. Como las TRAP son
excepciones software, se ejecutan en instantes de tiempo predecibles y se puede evitar que
interrupciones y programa principal las usen a la vez.
En cualquier caso, el nivel de las interrupciones temporizadas debe ser inferior a 7, porque el
nivel 7 no es enmascarable y dificulta mucho la depuración (la ejecución de la rutina de atención a
la interrupción puede ser a su vez interrumpida por una nueva petición de interrupción).
Si el nivel es 7, aunque pongamos un punto de parada en la rutina de atención a la interrupción y
el programa aparentemente se detenga al llegar a él, la generación y atención de interrupciones no
se detiene y nuestro programa sigue ejecutándose de una manera indeseada y difícil de predecir.
5.3.3.1 Proceso principal
El proceso principal siempre existe y debe: inicializar los objetos del sistema, inicializar el HW,
habilitar la aparición de interrupciones e inicializar ambos procesos de interrupción periódica
(_init). Los sistemas empotrados de tiempo real suelen contener un bucle indefinido (bucleMain)
que puede llevar a cabo tareas sin requisitos temporales estrictos, como puede ser en nuestro caso la
lectura del teclado y la presentación en pantalla de los menús. Los resultados finales se pueden
mostrar en la rutina de atención a la interrupción porque en ese momento se ha terminado la
reproducción y visualización de la melodía y ya no pueden ser retardados por la impresión en
pantalla.
Figura 12. Representación temporal de los 3 procesos.
34
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
En nuestro caso el bucle del programa principal podría ser aproximadamente:
BucleMain:
while (true)
if (estado.jugando==false)
estado.menús()
estado.jugando=true
else
if (tecla.leer(relojes,puerto)==TECLA_VALIDA_JUEGO)
resultado.actualizarTecla(tecla)
endif
endif
endwhile
La rutina general de inicialización sería similar a:
Init:
swInit()
hwInit()
* inicializa todos los objetos/variables SW
* inicializa las interrupciones y los puertos
Este proceso principal es el menos prioritario de los tres porque el teclado o la escritura en la
pantalla no son acciones tan críticas en el tiempo.
5.3.3.2 Primera interrupción periódica
Contendrá las funciones críticas en el tiempo relacionadas con el refresco de los leds y la caída
de las piezas, en particular:
•
Actualizar los relojes (i.e. contadores de tiempo) correspondientes.
•
Si estado.jugando==true
o Si se ha agotado el tiempo de excitación de la columna actual de leds,

Pasar a la siguiente columna.
o Si se ha agotado el tiempo de permanencia en la línea actual,

Mover la pieza hacia abajo.
Su ejecución es cíclica, discontinua y sucede a intervalos regulares de tiempo; es concurrente con
el proceso principal y la otra interrupción periódica. Sin embargo, sólo debe poder interrumpir al
programa principal, no así a la otra interrupción periódica cuya prioridad, por razones que
explicaremos posteriormente, será mayor. Por tanto, esta última sí que podrá interrumpir a la que
ahora nos ocupa.
Esta interrupción será la encargada de controlar la
relacionada con el refresco de la matriz de leds, refresco del
funcionamiento. Por esta razón, este proceso debe tener
principal. Adicionalmente, también será la encargada de la
el movimiento de caída de las piezas.
parte de temporización del sistema
cual depende directamente su correcto
mayor prioridad que el programa
temporización necesaria para articular
35
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
En nuestro sistema la rutina de atención a la interrupción periódica podría ser similar a:
InterrupcionPeriodica1:
guardarRegistros()
interrReset()
relojes.actualizar()
if (estado.jugando==true)
if (relojes.tiempoExcitacionColumna==PERIODO_REFRESCO_MATRIZ)
leds.excitarSiguienteColumna()
relojes.tiempoExcitacionColumna=0
endif
if (relojes.tiempoCaidaPieza==PERIODO_CAIDA_PIEZA)
relojes.tiempoCaidaPieza=0
juego.muevePiezaAbajo()
endif
endif
restaurarRegistros()
RTE
5.3.3.3 Segunda interrupción periódica
Contendrá funciones críticas desde el punto de vista temporal, en este caso relacionadas con la
correcta gestión de la reproducción de la melodía durante el juego. En particular las de:
•
Actualizar los relojes (i.e. contadores de tiempo) correspondientes.
•
Si estado.jugando==true
o Si se ha terminado de reproducir una nota,

Pasar a la siguiente nota.
o Si es la última nota,

Pasar a la primera nota.
Su ejecución es cíclica, discontinua y sucede a intervalos regulares de tiempo. Es concurrente
con el proceso principal y la otra interrupción periódica, procesos a los que debe poder interrumpir
(pero por los que no puede ser interrumpida). Es el proceso con mayor prioridad de los tres. Esta
interrupción es la encargada de controlar la temporización necesaria para gestionar la adecuada
duración de cada una de las notas que componen la melodía de juego.
Respecto a la prioridad asignada a cada una de las interrupciones periódicas, debe tenerse en
cuenta el siguiente criterio: dados dos procesos cualesquiera deberá tener mayor prioridad aquél
cuya interrupción requiera una oportuna respuesta o debida atención más inmediata. Desde este
punto de vista, esta última interrupción es la que deberá tener mayor prioridad de las dos. El retardo
debido a las acciones necesarias para llevar a cabo el refresco de los leds (i.e. operaciones de
escritura en el puerto de salida) puede provocar que la melodía no se escuche correctamente (e.g.
provocando que las notas tengan una duración aparente mayor de la que en realidad les
corresponde). Sin embargo, el retardo debido a las operaciones necesarias para poder gestionar la
reproducción de las notas (i.e. parar y arrancar el timer correspondiente para la generación una onda
cuadrada de la frecuencia requerida según la nota) no debe suponer problema alguno en cuanto al
oportuno refresco de la matriz de leds (visualmente imperceptible en cualquiera de los casos).
36
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
En nuestro sistema la rutina de atención a esta interrupción periódica podría ser similar a:
InterrupcionPeriodica2:
guardarRegistros()
interrReset()
relojes.actualizar()
if (estado.jugando==true)
if (relojes.tiempoNota==melodias.notaActual.duracion)
relojes.tiempoNota=0
if (melodias.terminada==true)
melodias.notaActual=0
melodias.terminada=false
else
melodias.siguienteNota()
endif
endif
endif
restaurarRegistros()
RTE
5.4 Modelo de implementación orientativo
5.4.1 Codificación
Una vez que, tras el diseño, disponemos de los modelos estáticos y dinámicos, llega el turno de
convertir nuestras ideas y modelos en código ejecutable, y la dependencia del lenguaje de
programación es completa. Las normas de codificación en ensamblador de rutinas con paso de
parámetros, se pueden encontrar en [3] y en el libro de SEDG [7].
A la hora de codificar debe tener en cuenta los criterios de calidad establecidos en la asignatura:
•
La estructura general del programa en ensamblador debe responder a lo comentado en
la sección 4.1.2 de [3].
•
Cada subrutina debería tener un único punto de comienzo y un único punto de
terminación, y no debería entrelazarse con otras subrutinas (según se comenta en el
documento “Dudas y preguntas frecuentes del LSED”). Sí que es conveniente que las
rutinas se aniden (una rutina llame a otra para realizar una cierto cálculo y al terminarse
la segunda rutina, pueda continuar la ejecución de la primera).
•
Debería emplear un buen número de rutinas (subrutinas, métodos o funciones), que le
ayuden a dividir cada problema en subproblemas, y que no resulten muy extensas (y por
lo tanto difíciles de entender y depurar). Algunas rutinas recomendadas se han ido
incluyendo a lo largo de este enunciado. Si pensamos en una media de casi 3 métodos por
objeto, 25 rutinas parece un número mínimo exigible para esta práctica.
•
Debe emplear constantes EQU o #define que permitan reconfigurar fácilmente el
sistema (las instrucciones no deberían usar números mágicos). Ejemplos típicos podrían
ser:
o Una constante que permita fácilmente variar la frecuencia de las interrupciones
temporizadas (FREQ_INT EQU ... o bien #define FREQ_INT...).
37
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
o Una constante para modificar el retardo antirrebotes del teclado (RET_REBOT
EQU... o bien #define RET_REBOT...).
•
Debe emplear modos de direccionamiento variados y apropiados (indexado, indirecto,
post-incremento...) y usar estructuras de datos que agrupen datos interrelacionados y que
faciliten la implementación (búferes, tablas de valores...). Emplear estas técnicas suele
producir código más compacto y elegante, evitándose frecuentemente el abuso de la
desaconsejable técnica de “copiar, pegar y modificar”.
•
Debe incluir comentarios orientativos en el código (comentarios que aporten
información al que los lea, no que se limiten a parafrasear el código). Un ejemplo
paradigmático de un mal comentario es:
o ADD.L #1,D0 * incrementa el registro D0
•
Debe emplear typedef, struct, switch para producir soluciones elegantes, en C. Por cada
objeto debería haber al menos un typedef y un struct. Por ejemplo:
typedef struct {
WORD frecuencias[MAX_NUM_NOTAS];
WORD duraciones[MAX_NUM_NOTAS];
...
} Tmelodia;
typedef struct {
Tpieza piezas[MAX_NUM_PIEZAS];
...
} Tpiezas;
•
Un empleo abundante y adecuado de #include para dividir el código en subsistemas
coherentes, en C. Al menos debería haber al menos un #include por objeto. Con este
propósito le resultarán de utilidad las plantillas para la creación de un nuevo archivo .c o
de un nuevo archivo .h disponibles en la web de la asignatura [17].
•
Debe emplear pocas variables globales, sobre todo en C. Sólo parece haber 4 objetos
globales: estado, relojes, puerto y resultados. Para minimizar las variables globales debe:
o usar variables static locales a los métodos o funciones en C, para que esas
variables sólo puedan ser usadas por ese método, pero no sean variables locales
que se pierdan al terminar la ejecución de la rutina, y que así en la siguiente
ejecución de la rutina, mantengan el valor que tenían al acabar la anterior
ejecución:
void rutinaInterrupcionConStaticLocal()
{
static Tmelodias melodias=...;
...
}
o pasar parámetros a los métodos o funciones en C: por valor (si el parámetro no va
a ser variado por la rutina) o por referencia (en caso contrario).
38
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
rutinaCopiaParam(int paramPorValor,int *paramPorRefer)
{
* parametroPorReferencia= parametroPorValor;
...
}
•
el empleo de punteros y arrays en C es recomendable para acceder a estructuras de
datos complejas de una manera elegante. Por ejemplo, los arrays de frecuencias y
duraciones antes mostrados en la Tabla 1.
•
No se debe emplear goto, en C.
•
Etc.
5.4.2 Ejemplo de una posible implementación del objeto relojes
Dado que los lenguajes de programación disponibles en este laboratorio no son orientados a
objetos, su implementación requiere seguir una cierta metodología.
5.4.2.1 Declaración de un objeto: tipo y variable
Cada objeto puede ser implementado como un struct en C que contiene todos los datos, o
implementarse como un conjunto de datos en ensamblador. Hemos elegido una implementación
incrementando contadores, aunque sería perfectamente posible implementar los relojes por medio
de contadores que decrementan.
typedef struct {
int iTiempoNota; // contador para la duración de cada nota
int iTiempoDisplay; // contador de refresco de leds cada 5 ms
int iTiempoCaidaPieza; // contador para el tiempo de caída de cada pieza
…
} Trelojes;
Hay que declarar un objeto de tipo Trelojes, en el ámbito adecuado. Si consideramos que
Trelojes es un objeto global porque debe ser consultado por el programa principal y las
interrupciones, al comienzo de nuestro programa, en la zona de variables globales incluiremos:
// objeto que permite contar el tiempo para las notas musicales
// y para el refresco de los leds
Trelojes relojes;
5.4.2.2 Implementación de cada método
Los métodos de cada objeto, tendrán un nombre que comenzará con el nombre del objeto, un
guión bajo y el nombre del método. El primer parámetro de cada método será un puntero al objeto,
para poder leer sus datos y modificarlos.
// número de interrupciones en cada milisegundo
#define INTERR_POR_MS 1
// poner a 0 todos los contadores de tiempo
void relojes_reset(Trelojes *pRelojes)
{
pRelojes->iTiempoNota=0;
39
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
pRelojes->iTiempoDisplay=0;
…
}
// configurar las interrupciones periódicas
// y poner a 0 todos los contadores de tiempo
void relojes_inic(Trelojes *pRelojes)
{
relojes_reset(pRelojes);
…
}
// incrementa todos los contadores de tiempo
void relojes_actualizar(Trelojes *pRelojes)
{
// cada milisegundo
pRelojes->iTiempoNota++; // incrementamos los tiempos en ms
pRelojes->iTiempoDisplay++;
…
}
Cuando sea necesario llamar a un método del objeto relojes se hará como indica:
relojes_inic(&relojes);
5.4.2.3 Implementación como objeto local del programa principal o de la rutina de interrupción
Si sólo se accediese al objeto desde la rutina de atención a la interrupción o desde rutinas
llamadas por ella, no se debería declarar el objeto como global sino como local a la rutina de
atención.
#include “m5272lib.h” // definición del tipo BOOL y sus constantes
void rutina_tout0(void)
{
static BOOL bPrimeraEjecucion=TRUE;
static Trelojes relojes;
…
// inicializa todos los objetos static sólo la 1ª vez
if (bPrimeraEjecucion==TRUE)
{
relojes_inic(&relojes);
…
bPrimeraEjecucion=FALSE;
}
…
relojes_actualizar(&relojes);
}
5.4.3 ¿Cómo modificar un bit del puerto de salida?
En esta práctica, sólo 2 de los 3 procesos deben usar el puerto: el programa principal y la primera
interrupción periódica encargada del refresco de los leds, aunque usen bits diferentes del mismo.
Como los dos procesos se ejecutan aparentemente en paralelo, si no se tiene cuidado, puede haber
conflictos entre ellos, llegando al extremo de que un proceso modifique sin querer los bits o los
datos correspondientes a otro.
40
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Tabla 3. Detalle de las diferentes conexiones al puerto de salida.
Puerto de salida 15 14 13 12 11 10 9
8
7
6
5
4
3
2
1
0
Conexión
F7 F6 F5 F4 F3 F2 F1 F0 C3 C2 C1 C0 T3 T2 T1 T0
En los tutoriales de C se emplea la rutina set16_puertoS(), para enviar un valor de 16 bits al
puerto de salida (la rutina equivalente en ensamblador hará aproximadamente un MOVE.W del dato
de 16 bits a la dirección del puerto). Sin embargo, como los puertos son unidireccionales, el
puerto de salida no puede ser leído. Esto implica que en ensamblador no se puede modificar
correctamente un bit del puerto de salida directamente haciendo un BSET, BCLR o BCHG de un bit
del puerto, porque estas instrucciones implican leer y escribir en el puerto. En C, no se puede
aplicar una máscara AND (operador &) u OR (operador |) directamente al puerto para modificar un
bit. En ambos casos es necesario emplear una variable auxiliar (lo que denominamos objeto Puerto).
Supongamos que los 4 bits menos significativos (0-3) se emplean para excitar las columnas T0T3 del teclado (como se explica en el tutorial del mismo), los bits 4-7 para excitar las columnas C0C3 de la matriz de leds, y que se emplean los bits 8-15 del puerto para excitar las filas F0-F7 de la
matriz.
Cada vez que el teclado quisiese excitar una de sus columnas (si se realizase el barrido), debería
poner un 1 en el bit correspondiente a esa columna del teclado, y un 0 en los otros 3 bits
relacionados con el teclado, respetando el valor que tuviesen los bits relativos a los leds. Si, por
ejemplo, se quiere excitar la columna 0 del teclado (T0), y se envía un 0x0001 al puerto, se comete
un error: además de excitar la columna adecuada, se están poniendo a 0 todos los bits que tienen
que ver con los leds, con la posible alteración del buen funcionamiento de la parte de visualización.
Para poner a 1 el bit de una columna del teclado (T0-T3), lo recomendado en ensamblador sería
realizar el BSET, BCLR o BCHG, sobre un registro que contiene el valor de la variable auxiliar
Puerto_variable (que contiene el último valor enviado al puerto), para a continuación actualizar la
variable auxiliar y enviar esa variable modificada al puerto. Tenga en cuenta que el puerto (y por lo
tanto la variable auxiliar) es de 16 bits, pero las funciones BSET, BCLR o BCHG, no pueden
modificar directamente una variable .W en una sola instrucción:
PUERTO_S
EQU $40000002
Puerto_variable
DC.W
* DIRECCION DEL PUERTO S
0
* esta rutina recibe a través de D0 el número del bit que poner a 1
PUERTO_SET_BIT:
MOVE.L D1,-(A7)
MOVE.W Puerto_variable,D1
BSET.L D0,D1
MOVE.W D1,Puerto_variable
MOVE.W D1,PUERTO_S
MOVE.L (A7)+,D1
RTS
Para poner a 1 el bit de una columna del teclado (T0-T3), lo recomendado en C sería:
#define MASCARA_TECLADO 0xFFF0 // asigna 0 a cada bit del teclado
#define EXCIT_TECLADO 0x0001
typedef struct {
WORD variableAux; // variable básica del objeto puerto
…
} TpuertoSalida;
41
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
TpuertoSalida puerto;
// numColumna es la columna del teclado que excitar: 0, 1, 2 o 3
void puerto_excitaColumnaTeclado(int numColumna)
{
…
// falta comprobar que numColumna<4
// tiene un 1 en el bit de cada una de las columnas del teclado
static WORD excitaTeclado[]={0x1,0x2,0x4,0x8};
// suponemos que variableAux contiene el último dato enviado al puerto
// borra sólo los bits del teclado
puerto.variableAux= puerto.variableAux & MASCARA_TECLADO;
// pone a 1 el bit adecuado en función de numColumna
puerto.variableAux= puerto.variableAux | excitaTeclado[numColumna];
set16_puertoS(puerto.variableAux); // envía el nuevo valor al puerto
…
}
Supongamos que los bits de las filas deben estar a 0 si queremos que la fila correspondiente se
encienda (de acuerdo con la Figura 3). Apagar los leds de todas las filas salvo la fila 0 (F0) supone
poner a 0 el bit de la fila 0, poner a 1 los otros 7 bits de filas, y no alterar los bits del teclado o las
columnas:
#define MASCARA_FILAS 0xFF00 // asigna 1 a cada bit de filas F0-F7
#define MASCARA_F0 0xFEFF // asigna 1 al bit de la fila F0
void puerto_fila0Encender(void)
{
// suponemos que variableAux contiene el último dato enviado al puerto
// pone a 1 los bits de filas
puerto.variableAux = puerto.variableAux | MASCARA_FILAS;
// pone a 0 el bit adecuado
puerto.variableAux = puerto.variableAux & MASCARA_F0;
set16_puertoS(puerto. variableAux); // envía el nuevo valor al puerto
}
Supongamos que para poder encender leds de una columna debemos poner a 1 el bit
correspondiente del puerto (de acuerdo con la Figura 4). Como sólo una de las columnas puede
estar activa a la vez, los demás bits de columnas deben estar a 0, y para encender la segunda
columna (C1) sin alterar las filas o el teclado podríamos escribir en C:
#define MASCARA_COLUMNAS 0xFF0F // vale 0 en los bits de columnas C0-C3
#define MASCARA_C1 0x0020 // vale 1 en el bit de la columna C1
void columna1Activar(void)
{
// suponemos que variableAux contiene el último dato enviado al puerto
// pone a 0 los bits de todas las columnas
puerto.variableAux= puerto.variableAux & MASCARA_COLUMNAS;
// pone a 1 el bit adecuado
puerto.variableAux = puerto.variableAux | MASCARA_C1;
set16_puertoS(puerto.variableAux); // envía el nuevo valor al puerto
}
42
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
5.4.4 Optimización
Aunque la optimización del código (en cuanto a consumo de memoria o de tiempo de CPU) no
se puede llevar a cabo hasta la fase de implementación, un mal diseño o una mala arquitectura
pueden hacer imposible esta labor en la fase de implementación, obligando a una reconsideración
del diseño. Así, si nuestra arquitectura intentase actualizar el visualizador o generar las notas de
audio desde el programa principal, los requisitos de temporización de estas tareas serían muy
difíciles de cumplir y se podría producir un funcionamiento incorrecto: al tratarse de un defecto
estructural, cualquier optimización puede estar condenada al fracaso si no revisamos la arquitectura.
Aunque éste no es nuestro caso (y la arquitectura propuesta puede satisfacer los requisitos del
enunciado), dado que en el LSED las prácticas son de tiempo real, no es extraño que el alumno se
vea obligado a emplear una o varias de estas estrategias de optimización para conseguir solucionar
el problema planteado por el enunciado.
5.4.4.1 Optimización de pequeñas rutinas en C
Si una rutina es pequeña se pierde más tiempo en el proceso de entrar y salir de la rutina, que en
ejecutar la rutina propiamente dicha. En estos casos puede ser interesante definirla como inline y
activar un nivel de optimización del compilador distinto de 0, de tal manera que el compilador no
genera una verdadera rutina y una verdadera llamada a rutina (con paso de datos a través de
registros o de la pila), sino que simplemente inserta el código equivalente en el lugar donde se
llamaría a la rutina, con el consiguiente ahorro de tiempo de ejecución. Por ejemplo:
Trelojes relojes; // declaración del objeto
// rutina que deseamos ejecutar rápidamente
inline void relojes_reset(Trelojes *pRelojes)
{
pRelojes->iContadorBase=0;
pRelojes->iTiempoNota=0;
pRelojes->iTiempoDisplay=0;
…
}
// rutina que invoca a la de puesta a 0 de relojes
void otraRutina(void)
{
…
relojes_reset(&relojes);
…
}
El código optimizado generado por el compilador será equivalente a haber escrito directamente:
// código equivalente “generado” por el compilador
Trelojes relojes; // declaración del objeto
void otraRutina(void)
{
…
relojes.iContadorBase=0;
relojes.iTiempoNota=0;
relojes.iTiempoDisplay=0;
43
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
…
}
Aunque esta última implementación es más reducida y más rápida, escribirlo directamente así
resulta mucho menos elegante en general, ya que el procesamiento del objeto relojes se realiza
directamente sin utilizar métodos propios del objeto. Variaciones en el objeto relojes, por tanto,
requerirían variar distintas partes del código y no únicamente los métodos del propio objeto relojes.
6. Descripción de la sesión -1 (antes de ir al laboratorio B-043)
Aunque al principio le resulte tedioso, recomendamos al alumno que se tome su tiempo para
formarse con los libros de apoyo al laboratorio publicados. Concretando algo más, debería leer,
antes de empezar las sesiones del Laboratorio, al menos:
•
El tema 6 (de temporizadores) del libro de SEDG [9]. Prestar especial atención a la
generación de interrupciones en tiempo real.
•
El libro de tutoriales de manejo de la plataforma ENT2004CF [3]. Como mínimo los
tutoriales relacionados directamente con la práctica (temas 1, 2, 3, 4, 5, 7 y 8).
•
El tutorial de utilización y la ayuda para el entorno de desarrollo EDColdFire v3.0 [4], en
especial el tema 3.
•
El capítulo 4 de [5]: con el epígrafe 4.1 y 4.2 de dicho manual le bastará.
•
El breve manual del Osciloscopio HAMEG HM-407 [6], en el caso de no haberlo
manejado anteriormente.
•
Los documentos de Dudas y Problemas Frecuentes en ensamblador y en C [7][8].
También debería bajar de Internet el software EDColdFire (que incluye el ensamblador del
MCF5272, y también el compilador GCC integrado para desarrollar la práctica en lenguaje C), y
aprender a manejarlos en su casa. Estos programas, el manual del osciloscopio y el documento de
dudas se encuentran disponibles a través del portal del LSED (http://lsed.die.upm.es/).
Con el fin de aprovechar al máximo las sesiones en el Laboratorio, que son un recurso muy
limitado, el alumno debe traerse los programas ya escritos de casa, donde los habrá ensamblado con
EDColdFire para comprobar que el código no tiene errores de sintaxis. Durante la sesión de
Laboratorio, el alumno volverá a ensamblar el programa y lo ejecutará en la plataforma
ENT2004CF. Encontrará errores que ya no son de sintaxis, sino de ejecución, que corregirá en el
Laboratorio: la labor de depuración es fundamental.
No terminaremos este apartado sin mencionar algo obvio: el alumno debería conocer la
arquitectura y el juego de instrucciones del procesador MCF5272. Recomendamos que para ello
emplee la bibliografía de apoyo a la asignatura Sistemas Electrónicos Digitales como [9].
6.1 Comentarios sobre las conexiones
En relación a las diferentes conexiones con el puerto de salida deben tenerse en cuenta los
siguientes aspectos:
44
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
En el tutorial de utilización del EDColdFire [4] y en la ayuda del programa está dibujado
el patillaje de los puertos; es decir, qué significa cada terminal de la plataforma (el dibujo
está hecho tal como se ve el conector de la plataforma desde fuera, no hay que
imaginárselo al revés o en espejo).
•
En el tutorial de la placa auxiliar del teclado y del LCD (TL04) (tema 7 de [3]) están
igualmente disponibles los 16 terminales de entrada y los 16 de salida. Éstos están
también disponibles en la web de la asignatura [18].
•
En la placa auxiliar TL04, las entradas y salidas están numeradas de la misma manera
que en los esquemas de entradas y salidas disponibles en web y en [3]. Uno de los
conectores negros hembra de la placa TL04 está conectado a los pines 1-13 (ambas filas
del mismo conector negro están redundantemente conectadas a los mismos pines) y
el otro está conectado a los pines 14-25, también de manera redundante (el 26 del
conector negro no está conectado).
•
En el futuro va a ser muy importante que la masa de la plataforma (disponible en los
conectores DB25 y en la placa auxiliar) esté conectada a la masa de la fuente de
alimentación (esto es, la masa debe ser única). Todos los terminales que se indican
como masa en los conectores de la plataforma son el mismo punto (sólo necesitamos
conectar uno de ellos).
•
Para las conexiones se deben usar tiras de 8x1 y 4x1 pines macho-macho planos, sin
tornear, largos (25 mm), de 2,54 mm de paso. En la web de la asignatura se han
publicado fotos sobre cómo conectar el HW de la práctica a la placa TL04 [19]. Estos
sencillos conectores macho debéis soldarlos a vuestros cables y facilitarán las conexiones
que hay que realizar cuando se llega al B-043 y que desconectar al irse. Conectar cables
rígidos directamente a los conectores negros está totalmente desaconsejado, porque
la conexión no es buena y provocará numerosos problemas.
7. Descripción detallada de la sesión 0
Para comenzar a abordar la Práctica en sí, el alumno tendrá dos primeras sesiones de Laboratorio
introductorias en las cuales se familiarizará con el entorno de desarrollo Hardware (la plataforma
ENT2004CF, aunque por motivos de seguridad, el alumno no conecta directamente su sistema al
MCF5272, sino a una tarjeta de interfaz compuesta de un primer buffer digital, un conjunto de leds,
una etapa de optoacopladores, y un segundo buffer digital), desarrollará el hito 1 y terminará de
adquirir habilidad con el entorno de desarrollo EDColdFire (que, como bien sabe, debe haber usado
previamente antes de ir al laboratorio B-043). Las partes de que se compone esta primera sesión de
laboratorio son:
•
Realizar un pequeño tutorial inicial descrito en el capítulo 3 de [3].
•
Realizar el tutorial de manejo del teclado del capítulo 7 [3]. Con este tutorial se
pretende que el alumno conozca y aprenda el manejo del teclado disponible en la placa
TL04 que utilizaremos como subsistema hardware de entrada de datos. De las 3 partes de
las que se compone el tutorial de manejo de la placa TL04 sólo hay que realizar el tutorial
de manejo del teclado, que permite imprimir en la pantalla del ordenador.
45
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
Ejecutar, depurar y modificar un primer programa; este programa debe pedir al usuario
que seleccione un nivel de dificultad (de entre los 3 posibles) pulsando una de las 3 teclas
asignadas (i.e. 1, 4 o 7), y el programa debe generar un mensaje en pantalla informando
del nivel de dificultad seleccionado. A continuación se solicitará al usuario la pulsación
de la tecla A que debe dar comienzo al juego. Si la tecla pulsada fuese distinta, deberá
presentarse un mensaje de error por pantalla advirtiendo al usuario de que la tecla que
debe pulsar debe ser la A. Veamos un ejemplo de funcionamiento del programa.
Sistema: Elija el nivel de dificultad del juego: (1) Fácil, (4) Medio, (7) Difícil.
Usuario: Pulsa 1.
Sistema: Nivel de dificultad seleccionado: Fácil. Pulse A para comenzar la partida...
Usuario: Pulsa 1.
Sistema: Tecla no válida. Por favor pulse A para jugar…
7.1 Método de trabajo
En el PC de laboratorio, deberá crear un directorio de trabajo colgando de la carpeta
“c:\alumnos” (carpeta para la que dispondrá de permisos de escritura). Ponga a ese directorio el
nombre de su código de pareja de laboratorio (por ejemplo, MT23). Dentro de él vaya creando un
directorio por cada sesión de acuerdo con el plan propuesto en el enunciado (sesion_1, sesion_2,
etc.).
Asegúrese de grabar los programas modificados en una memoria FLASH, o enviarlos por email
al final de la sesión de trabajo. Para evitar problemas de copias no deseadas de su SW por parte de
otros alumnos, al final de cada sesión debe borrar los ficheros .ASM, .C o .H que constituyan su
práctica. Recuerde que se realizarán entregas electrónicas del SW y habrá verificación de plagios.
Debe guardar al menos 2 copias en algún soporte (correo electrónico, memoria flash...).
Recuerde que el contenido de los discos duros puede ser borrado como consecuencia de las
tareas periódicas de mantenimiento del laboratorio.
Trabajar directamente en un dispositivo de tipo pendrive con el EDColdFire en el B-043 puede
dar problemas de compilación en algunos casos. Si sucede, se recomienda copiar los ficheros al
disco duro (carpeta “c:\alumnos”), trabajar con ellos, y al acabar la sesión, copiarlos en el pendrive
y borrarlos del disco duro. En todo caso, usar directamente este tipo de dispositivos ralentiza el
proceso de compilación y ejecución.
El modo correcto de abrir el programa EDColdFire es desde el menú de Inicio / Todos los
programas, o desde el icono que se crea en el escritorio al instalar.
7.2 Tutorial inicial
Viene descrito en el capítulo 3 de [4]. Fuera del laboratorio B-043 puede hacer algunos de los
pasos que figuran en dicho libro.
Como parte de este tutorial inicial se recomienda también la ejecución del programa
Cochefantastico.asm.
46
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
En el laboratorio, el código fuente original de Cadena.asm y CocheFantástico.asm no se
puede modificar, está protegido contra escritura. Para trabajar con él, haga una copia en su
directorio de trabajo. Todos los tutoriales se encuentran en el directorio c:\archivos de
programa\DIE-UPM\EDColdFire\tutoriales...
7.3 Tutorial del manejo del teclado de la placa TL04
Este tutorial viene descrito en el capítulo 7 de [3]. Con este tutorial se pretende que el alumno
conozca y aprenda el manejo del teclado disponible en la placa TL04 que utilizaremos como
subsistema hardware de entrada de datos. De las 3 partes de las que se compone el tutorial de
manejo de la placa TL04 sólo hay que realizar el tutorial de manejo del teclado, que implementa la
exploración del teclado y presenta en la pantalla del ordenador la tecla pulsada.
7.4 Diseño, implementación y prueba de un primer programa
En la primera sesión el alumno debe completar su primer programa que permite elegir uno de los
3 niveles de dificultad. Para ello debe seguir la estructura que se comenta en los siguientes
apartados.
7.4.1 Estructura básica de los programas que desarrolle
A continuación incluimos el esqueleto del programa a desarrollar. Éste contiene las 5 partes de
las que se habla en el apartado 4.1.2 de [5] y en [3]. Además, la nomenclatura que se sigue para
nombrar las variables y subrutinas es la misma que la comentada en dicho manual.
Con el símbolo <...> se representa algo que puede bien estar vacío, o ser una instrucción o un grupo de
instrucciones que han sido omitidas.
*************************************************
*
ZONA DE CONSTANTES
<...>
ORG <valor>
*************************************************
*
ZONA DE VARIABLES GLOBALES
<...>
sinusoide DC.W …
****************************************************
*
PROGRAMA PRINCIPAL
****************************************************
PPAL
<...>
* Modo supervisor. Inhabilita interrupciones
<...>
* Mueve el puntero de pila a una región válida
BSR swInit
* Subrutina configuración completa del SW
BSR hwInit
* Subrutina configuración completa del HW
<...>
* Habilita las interrupciones CPU
BUCLE
END
BSR bucleMain
BRA BUCLE
PPAL
* Bucle de programa principal.
*************************************************
47
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
*
ZONA DE SUBRUTINAS
<...>
* Subrutina de configuración completa del hardware
hwInit: <...>
RTS
* Subrutina de inicialización de las variables que lo necesiten
swInit: <...>
RTS
* Subrutina que contiene el programa principal
* cuya ejecución es típicamente periódica en el LSED
bucleMain:
<...>
BRA FIN_MAIN
ERROR:
<...>
FIN_MAIN
RTS
****************************************************
*
ZONA DE RUTINAS DE ATENCIÓN A LAS INTERRUPCIONES
****************************************************
* Rutina de atención a las interrupciones en el caso de
* que sean necesarias
INTERR: <...>
FININTER RTE
7.4.2 Subrutina para configurar el HW (hwInit)
En esta subrutina se deben incluir las acciones necesarias para configurar cada uno de los
recursos hardware que se vayan a utilizar: interrupciones, puertos,... Hay que prestar especial
atención a la configuración de recursos que comparten los mismos registros de configuración: por
ejemplo las interrupciones periódicas y las interrupciones externas. Sea muy cuidadoso en la
inicialización de estos registros.
En relación con la frecuencia de las interrupciones periódicas se recomienda la configuración de
estas interrupciones a una frecuencia de, por ejemplo, 1 KHz, a partir de la cual se puedan obtener
fácilmente frecuencias menores para implementar los diferentes relojes que se necesitan a lo largo
de la práctica.
7.4.3 Si tiene dudas o problemas...
Se recomienda al alumno que, antes de empezar a trabajar, lea el documento de Dudas y
Problemas Frecuentes del LSED, o su versión para programación en C.
7.5 Nociones sobre depuración de programas
En este apartado se comentan algunas nociones interesantes para la depuración de programas. La
depuración consiste en la búsqueda de errores durante el funcionamiento del programa, no durante
la fase de ensamblado o compilación. En relación con los errores vamos a considerar cuatro tipos
característicos:
•
NO sistemáticos y ocasionales: son errores que no siguen una sistemática a la hora de
producirse, lo hacen de manera ocasional. Estos errores son los más complicados de
detectar puesto que son difíciles de reproducir.
48
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
NO sistemáticos pero frecuentes: aunque no siguen una sistemática, al ser frecuentes
permiten reproducirlos fácilmente y definir un proceso de búsqueda.
•
Sistemáticos pero no frecuentes: en este caso al producirse bajo unas mismas
condiciones, son errores fácilmente reproducibles y por tanto depurables.
•
Sistemáticos y periódicos: se producen de forma periódica y en la mayoría de los casos
tienen que ver con el funcionamiento de las interrupciones periódicas.
En los apartados siguiente describiremos un protocolo (o conjunto de pautas a seguir) de
depuración o protocolo de búsqueda de errores aplicables en el caso de tener algún error de los
últimos 3 tipos. Para el caso de errores no sistemáticos y ocasionales se ofrecerán algunos
comentarios o pautas sobre las acciones de depuración que se pueden hacer para localizar el error.
7.5.1 PASO 1: Obtención de una prueba fallida y previsión de la salida
En este primer paso se trata de verificar los casos de uso propuestos en el enunciado y obtener un
conjunto de pruebas lo más concretas posibles para las cuales el sistema no se está comportando
correctamente (según las especificaciones). Si el número de pruebas asociado a un caso de uso es
pequeño (ej: pulsaciones sobre todas las teclas) se pueden realizar todas las pruebas (ej: pulsar todas
las teclas y analizar comportamientos similares: entre teclas de la misma fila o columna por
ejemplo). La información del tipo de error que producen unas u otras pruebas nos puede dar
información muy valiosa a aplicar posteriormente en el segundo paso: localización del error.
Una prueba fallida está compuesta de dos elementos imprescindibles:
Un conjunto de entradas o acciones concretas (ej: pulsa la tecla C) que originan o producen una
salida o un comportamiento erróneo.
Realizar una previsión de cómo se debería comportar el sistema ante esas entradas o acciones
(considerando el comportamiento correcto). Esta fase es la más laboriosa porque la previsión se
debe realizar a bajo nivel (a nivel de registro, variable o cable), pero es imprescindible para
garantizar el éxito en la localización posterior del error.
7.5.2 PASO 2: Localización del error
Con la prueba fallida obtenida en el paso anterior, ejecutamos el programa (o circuito) y
observamos algún efecto de salida del error (algún comportamiento erróneo). Un comportamiento
erróneo se produce cuando hay un desajuste en ese punto del programa (o circuito) entre la
previsión realizada y el valor obtenido o medido en una variable, registro o señal.
Una vez detectado el comportamiento erróneo disponemos de dos puntos principales para
comenzar el proceso de localización del error (búsqueda):
•
El punto de inicio: comienzo del programa, inicio de las señales de entrada,...
•
El punto final: lugar donde se detectó un desajuste entre la previsión para esa prueba y
los valores reales de comportamiento.
El proceso de búsqueda puede comenzar desde el punto de inicio (Forwardtracking) o desde el
punto final (Backtracking). En ambos casos es necesario:
49
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
Analizar las entradas y salidas de cada módulo. En el caso de “forwardtracking” si
tanto las entradas como las salidas están bien (coinciden con la previsión) pasamos al
siguiente módulo. En el caso de “backtracking” si tanto las entradas como las salidas
están mal (no coinciden con la previsión) pasamos a analizar el módulo anterior.
Cuando se detecta el módulo que está produciendo el error se comienza a analizar las diferentes
partes del módulo utilizando las mismas estrategias de “forwardtracking” o “backtracking” en cada
una de las partes hasta localizar una unidad atómica (indivisible, por ejemplo instrucción en
programación o integrado en HW) donde las entradas están bien y las salidas mal. En este punto
hemos localizado el error.
7.5.2.1 Comentarios adicionales
Algunos comentarios adicionales aplicables al proceso de búsqueda del error:
El proceso de localización del error requiere realizar varias ejecuciones del programa (o circuito)
hasta determinar el módulo o bloque donde se encuentra dicho error. Es muy importante repetir las
ejecuciones del programa realizando siempre la misma prueba. En algunos casos es difícil realizar
la misma prueba pero se debe intentar reproducir las condiciones más parecidas posibles: por
ejemplo, en el caso de probar pulsaciones largas de las teclas es complicado precisar en todos los
casos la misma duración de la pulsación, pero se debe intentar que sea lo más parecida posible.
Cuando se están analizando bloques grandes, la acción de depuración suele ser, ejecutar con
puntos de parada (situados al comienzo y al final del bloque) e inspección de variables, registros o
señales.
Para analizar dentro de un bloque, la acción de depuración suele ser ejecutar con puntos de
parada, paso a paso, e inspección de variables, registros o señales.
El proceso natural es BACKTRACKING pero en muchos casos es muy difícil identificar el
punto de final (punto donde la previsión y lo ocurrido son diferentes): un ejemplo es cuando un
programa genera un segmetation fault sin poder ver dónde ocurre. En estos casos no hay más
remedio que plantear una estrategia FORWARDTRACKING.
Nota importante para el LSED: cuando ocurre un error hardware que deja al programa
bloqueado, la opción más interesante para identificar el punto del final es mirar el contador de
programa. En el caso de que este contador tenga un valor que no corresponde con ninguna dirección
de nuestro programa, lo más probable es que el error se haya producido en la recuperación del
contador de programa de la pila: tras RTS o RTE.
La depuración de BUCLES puede ser muy laboriosa si el número de iteraciones del bucle es
muy elevado. En primer lugar hay que ver si el error se produce en el bucle. En ese caso, el consejo
es avanzar de varias en varias iteraciones utilizando la posibilidad que nos ofrecen los puntos de
parada. A medida que nos vamos acercando al error vamos reduciendo el número de iteraciones que
avanzamos y así hasta localizar la pasada del bucle que generó el error.
7.5.3 PASO 3: Determinación de la causa del error
Una vez detectado el error se debe detectar la causa u origen de dicho error: una instrucción no
válida, un modo de direccionamiento incorrecto, una variable sin inicializar,...
50
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
En este paso, al igual que en los anteriores, puede consultar al profesor, quien le dará las
orientaciones oportunas para encontrar la explicación del error.
7.5.4 PASO 4: Corregir el error
Una vez detectada la causa del error se debe corregir dicho error realizando un rediseño o
reimplementación de esa parte del programa o circuito.
Una vez realizada la modificación es necesario volver a probar el sistema con la misma
prueba que nos permitió localizar el error. Si el error ha sido correctamente corregido y no había
más errores adicionales, la prueba debe dejar de ser fallida y el sistema funcionará correctamente.
NOTA: en el caso de que el alumno se encuentre bloqueado en la búsqueda del error se propone
la posibilidad de cambiar de prueba fallida y repetir los 4 pasos que se proponen. Recuerde que en
cualquier paso puede consultar con el profesor.
7.5.5 Consejos para errores no sistemáticos y ocasionales
Este tipo de errores son los más complicados de detectar puesto que al ser ocasionales y no
seguir un patrón conocido, cualquier proceso de localización nos puede llevar mucho tiempo. Ante
esta situación, y en base a la experiencia de los profesores a lo largo de los últimos años, se
proponen las siguientes recomendaciones:
•
Un primer consejo es que sean otros ojos (diferentes a los que han implementado el
sistema) los que evalúen la posible causa del error. En este punto se aconseja a los
alumnos que pregunten a los instructores y a los profesores.
•
Cuando se dispone de versiones anteriores del programa o circuito se propone realizar
algunas de las acciones siguientes:
o Analizar las diferencias con la última versión del programa o circuito que
funcionaba correctamente.
o Deshacer los últimos cambios e ir introduciéndolos poco a poco comprobando, en
cada momento, si aparece o no el error.
•
En el caso de no disponer de una versión anterior, una estrategia interesante es modificar
de manera controlada el sistema (programa o circuito) desarrollado. Esta modificación
puede consistir en substituir un módulo por otro (e.g. si se usase el LCD, una alternativa
sería imprimir en la pantalla del EDColdFire) o bien desactivar alguno de los módulos:
o El último módulo implementado, el más complejo o el menos probado hasta la
fecha.
o El módulo relacionado con el origen de la acción que produce el fallo o el módulo
donde se detecta algún desajuste entre el comportamiento real y el esperado.
•
Otra acción interesante es analizar puntos intermedios que permitan detectar desajustes
entre el comportamiento real y el esperado.
51
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
Para los errores de los programas que producen un error del hardware de la plataforma, es
muy recomendable analizar los principales registros (PC, D0-D7 y A0-A7) con el fin de
extraer información útil que nos permita detectar el error. Algunas causas muy frecuentes
de este tipo de errores son:
o Variables no inicializadas que producen comportamientos aleatorios.
o Corrupción de la pila por mal uso de las instrucciones RTS y RTE.
7.5.6 Comentarios adicionales sobre depuración de programas
•
Antes de usar una función (o método) es necesario haberla declarado. Si no se hace,
el compilador supone que esa función va a devolver un 'int' (declaración implícita) y nos
dará avisos como los siguientes:
o warning: type mismatch with previous implicit declaration
o warning: previous implicit declaration of `funcionX'
o
warning: `funcionX' was previously implicitly declared to return `int'
•
Editar los ficheros fuentes (.c o .h) usando un editor que no sea el EDColdFire puede
provocar problemas de compilación, debido a una diferente gestión de los retornos de
carro por parte del compilador (caracteres que normalmente no se ven al editar). El
fichero afectado parece ser correcto (el EDColdFire lo muestra bien, pero el compilador
no lo procesa bien, pero se producen errores de compilación imprevisibles (el
EDColdFire lo muestra bien, pero el compilador no lo procesa bien). Se puede intentar
corregir el problema copiando el texto desde el EDColdfire, pegándolo sin formato en el
bloc de notas, volviendo a copiarlo y, finalmente, pegándolo en el EDColdFire.
•
Si la mayoría de los datos de un “array” o “struct” son constantes y no cambian durante la
ejecución del programa, se pueden inicializar directamente al declararlos, siempre y
cuando se declaren como 'static' (respuesta 32 de [8]). Para declarar e inicializar una
variable de tipo 'struct', se puede consultar el ejemplo 6.17 de [20] (no el 6.16, que es
muy poco recomendable). El ejemplo 6.18 explica cómo inicializar un 'array', lo cual es
extrapolable a 'arrays' contenidos en 'structs'.
•
Si se activan las optimizaciones del compilador, las variables globales que pueden ser
accedidas desde el programa principal y desde las interrupciones, deberían declararse
como volatile. Esta palabra clave indica al compilador que a la hora de optimizar trate de
manera especial estas variables porque pueden ser modificadas por las interrupciones en
instantes de tiempo impredecibles para el compilador. Ejemplo: 'volatile BOOL flag;'
(explicación adicional en el capítulo 8 de [20]).
•
Se ha publicado una implementación en C incompleta (pero funcional) de la función
printf, adaptada al EdColdFire por Víctor Miguel Morales [21].
52
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
8. Desarrollo recomendado
En este apartado se da una división y planificación orientativa del trabajo a realizar en el
laboratorio, organizados en forma de hitos que conseguir y sesiones de laboratorio semanales (en la
tabla se muestra la correspondencia entre sesiones e hitos):
Tabla 4. Relación entre sesiones de laboratorio e hitos a conseguir.
SESIÓN
0
1
2
3
4
5
6
7
8
9
10
HITO QUE CONSEGUIR
1
2
3
4
5
8.1 Hitos y sesiones orientativas
Esta es una planificación orientativa en relación al posible desarrollo de la práctica. En caso de
que los alumnos superen los objetivos planteados para una determinada sesión antes de la
finalización de la misma, se recomienda al alumno tratar de abordar los objetivos y tareas
planteados para la siguiente sesión.
Igualmente, y en relación con la redacción de la memoria final, se recomienda que la
realización de la memoria se vaya realizando a medida que se van consiguiendo cada uno de
los hitos descritos.
8.1.1 Sesión -1
Antes de asistir a su primera sesión de laboratorio es necesario preparar el trabajo fuera del
laboratorio, como se ha mencionada en un apartado previo. A través del portal web y de los libros
[3] y [4] encontrará recomendaciones y materiales que le resultarán útiles en esta labor.
8.1.2 Hito 1: Menús y visualización
Objetos implicados: Relojes, Leds, Piezas, Estado, Pantalla, Tecla y Puerto.
8.1.2.1 Sesión 0
Un primer objetivo ligado al hito 1 es desarrollar el sistema de menús para seleccionar el nivel de
dificultad y el momento en que da comienzo el juego.
53
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
El alumno comenzará a diseñar, implementar y depurar el primer prototipo del sistema. Una vez
completados los tutoriales del entorno y del teclado, el primer paso será implementar el sistema
de menús, empleando únicamente las 4 teclas mencionadas en este enunciado.
El siguiente paso consistirá en agregar interrupciones temporizadas a los menús. Una vez
completados los tutoriales de los temporizadores, deberá conseguir provocar interrupciones a 1
KHz, interrupciones que deberán habilitarse una vez pulsada la tecla ‘A’ y que deberán
contabilizarse mediante la oportuna actualización de un contador.
Es muy importante traer programas diseñados y escritos en casa, para aprovechar al máximo las
horas de laboratorio disponibles.
El plan de pruebas propuesto en esta sesión consistiría en probar cada una de las posibilidades
del sistema de menús, que las teclas no útiles son ignoradas y no provocan ningún problema, que el
objeto estado se actualiza correctamente y que los mensajes en pantalla son adecuados a cada
prueba. En relación a las interrupciones se deberá comprobar, haciendo uso de puntos de parada,
la correcta atención de las mismas prestando especial atención a la actualización del mencionado
contador.
8.1.2.2 Sesión 1
El objetivo de esta sesión consiste en incorporar el hardware necesario para visualizar el área de
juego basada en la matriz de leds.
Para ello se debe diseñar, implementar y probar dicho HW de visualización conectándolo al
puerto digital de salida. En este caso, el programa cocheFantastico puede servir para una prueba
básica incompleta de las conexiones. Como este programa va activando (poniendo a 1) cada uno de
los bits del puerto de salida y los demás los pone a 0, si se emplea una configuración como la del
enunciado, cuando el bit activado sea el de alguna de las columnas, se encenderán todas los leds de
esa columna.
8.1.2.3 Sesión 2
Finalmente, se propone como objetivo último del hito implementar las rutinas que permitan
mostrar una determinada pieza (para lo que deberá abordar el diseño de un primer modelo de pieza)
en alguna posición dentro del área de juego.
Para ello el alumno deberá emplear las interrupciones temporizadas añadidas durante la primera
sesión. En particular, deberá aprovechar las mismas para refrescar correctamente la matriz
aplicando las excitaciones oportunas en el puerto de salida.
El plan de pruebas para verificar el correcto funcionamiento consiste en comprobar que todos y
cada uno de los leds de las filas y las columnas se encienden correctamente al enviar al puerto de
salida los valores apropiados, sin que el teclado deje de funcionar. En este sentido, será importante
comprobar con el osciloscopio la correcta generación de las señales de excitación aplicadas a las
diferentes columnas de la matriz de leds, señales necesarias para su oportuno refresco.
A la hora de inicializar y pintar una determinada pieza deberá prestar especial atención a
las coordenadas de posición en las que decida hacerlo. Por el momento, y para simplificar el
proceso de verificación, asegúrese de “ubicar” la pieza en una posición adecuada, de tal modo que
la pieza al completo esté comprendida dentro del área de juego.
54
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
8.1.3 Hito 2: Movimientos
Objetos implicados: los mismos que para el hito anterior.
8.1.3.1 Sesión 3
Como parte de este segundo hito se propone ultimar el diseño del modelo de pieza permitiendo
la representación en la matriz de leds de todos los tipos de pieza considerados en sus múltiples
posibles formas. En este caso será importante verificar que el sistema es capaz de representar
cualquier tipo de pieza en cualquier posición (dentro del área de juego).
Igualmente, se abordará la implementación de todos los posibles movimientos contemplados en
el juego: traslación (hacia la izquierda, hacia la derecha y hacia abajo) y rotación (sólo hacia la
izquierda según giros de 90 grados en sentido anti-horario, al disponer de una única tecla de
rotación). En relación a este objetivo será importante verificar que los leds de la matriz se encienden
y se apagan correctamente (i.e. borrado) al realizar los diferentes movimientos de la pieza.
El plan de pruebas para esta sesión debe prestar especial atención a la robustez de los
métodos implementados para pintar y borrar una determinada pieza la matriz de leds. En
particular, debe comprobarse que el método diseñado para pintar sólo lo hace dentro de los límites
definidos para el área de juego. De este modo, y como parte del comportamiento esperado de
nuestro sistema, debemos comprobar cómo al mover sucesivamente la pieza hacia la derecha, ésta
acaba “desapareciendo” del área de juego. Igualmente, si deshacemos el recorrido anterior mediante
sucesivos movimientos hacia la izquierda, la pieza debe “aparecer” nuevamente en el área de juego.
Una prueba similar debe hacerse para el caso en que decidamos hacer desaparecer la pieza a través
del límite izquierdo del área de juego. En caso de intentarlo hacia abajo, es preciso destacar que no
será posible recuperar la posición original de la pieza al no contemplarse la posibilidad de realizar
movimientos hacia arriba (a menos que incluyamos código extra que lo permita, e.g. si la pieza cae
más de 5 líneas por debajo del límite inferior del área de juego, debe volver a ubicarse al comienzo
de la misma).
Otro detalle importante que debe tener en cuenta en todo este proceso de verificación es la
conveniencia de aprovechar la pantalla. Ésta puede ser aprovechada para presentar en ella
información que facilite las distintas comprobaciones requeridas (e.g. coordenadas de posición de la
pieza en el área de juego, rotación actualmente seleccionada, ocupación del área de juego, etc.).
8.1.3.2 Sesión 4
Finalmente, y para completar el Hito 2, en esta sesión se propone la implementación de la caída
de las piezas según el ritmo considerado para el nivel de dificultad elegido. Así, aprovechando las
mismas interrupciones empleadas para la temporización asociada al refresco, mediremos el tiempo
que una determinada pieza permanece en la misma línea provocando su descenso a la siguiente en
caso de que dicho tiempo supere el umbral establecido.
Recuerde la recomendación de tratar la caída automática de una pieza como una sucesión de
movimientos hacia abajo a intervalos regulares de tiempo que no están motivados por la pulsación
de la tecla correspondiente por parte del jugador. En este caso, dichos movimientos están motivados
por la detección de que el tiempo que lleva la pieza actualmente seleccionada en la misma línea, ha
superado el umbral definido. En este sentido, y a nivel de implementación, un único
55
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
procedimiento cuya oportuna llamada permita ejecutar dicho movimiento hacia abajo en
ambos casos (i.e. pulsación y timeout) es suficiente.
En esta ocasión, será importante verificar que tras ubicar una determinada pieza en una cierta
posición dentro de la pantalla, la pieza acaba desapareciendo de la misma tras sucesivos descensos
sin necesidad de ejecutar movimiento hacia abajo alguno.
Al término de esta sesión el alumno debería haber alcanzado el Hito 2. Durante la misma tendrá
lugar una revisión por parte de los profesores del estado del sistema en desarrollo. En este sentido
se prestará especial atención a que los alumnos hayan superado el Hito 1.
8.1.4 Hito 3: Colisiones
Objetos implicados: todos menos Melodías.
8.1.4.1 Sesiones 5 y 6
En ellas se debe implementar el juego propiamente dicho, incluyendo la necesaria detección de
las colisiones que puedan producirse como resultado de los diferentes movimientos de las piezas.
En caso de producirse una colisión al tratar de ejecutar un movimiento hacia abajo, deben
comprobarse todas las líneas del área de juego, haciendo desaparecer las que se hayan completado y
“repintando” las líneas superiores en el espacio liberado.
Una vez llevada a cabo la oportuna gestión de las líneas completadas, y dependiendo del estado
de ocupación del área de juego, deberán implementarse tanto la generación y puesta en juego de una
nueva pieza, como la detección del posible final del juego.
Asimismo, se deben calcular y mostrar los resultados contemplados, es decir, el número de líneas
completadas durante el juego.
Un posible procedimiento a seguir para verificar la correcta gestión de las colisiones podría
consistir en deshabilitar temporalmente la caída automática de las piezas. De este modo, resultará
más sencilla su comprobación cuanto éstas estén provocadas por los movimientos ejecutados por el
jugador. En particular, los diferentes casos de prueba que deberá comprobar son:
•
colisión de una pieza tras movimiento hacia la izquierda bien con el límite izquierdo del
área de juego o bien con otra pieza,
•
colisión de una pieza tras movimiento hacia la derecha bien con el límite derecho del área
de juego o bien con otra pieza,
•
colisión de una pieza tras movimiento hacia abajo bien con el límite inferior del área de
juego o bien con otra pieza,
o en este caso en particular, deberá comprobarse igualmente que, en caso de
completar una determinada línea, dicha línea es borrada y todas las que se
ubicaban encima son “repintadas” correctamente una línea más abajo. Esta prueba
puede extenderse al caso en que se completen simultáneamente dos, tres o incluso
cuatro líneas. Igualmente, podrá aprovecharse esta prueba para comprobar la
correcta actualización del contador del número de líneas completadas.
56
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
o otro de los aspectos importantes que deberá comprobar será la correcta
inicialización y puesta en juego de una nueva pieza. Concretamente, deberá
prestar especial atención a la decisión en cuanto a qué coordenadas iniciales de
posición asignar a cada nueva pieza. El objetivo en ese sentido será asegurar que,
inicialmente, sólo se pueda visualizar parcialmente cada pieza (e.g. al aparecer
una pieza en forma de L sólo se deberían “ver” en el área de juego los dos
primeros cuadrados correspondientes a la base o lado corto de la L).
•
colisión de una pieza tras movimiento de rotación (siempre hacia la izquierda o en
sentido anti-horario) bien con alguno de los límites del área de juego o bien con otra
pieza.
En una segunda etapa podría recuperarse la caída de las piezas para, en ausencia de dichos
movimientos, comprobar que las diferentes piezas comienzan a apilarse unas sobre otras hasta
agotar el espacio disponible en el área de juego dando lugar a la finalización del mismo.
8.1.5 Hito 4: Melodía de juego
Objetos implicados: Relojes, Estado y Melodía.
8.1.5.1 Sesiones 7 y 8
En este hito se propone incorporar el hardware analógico de audio y los mecanismos necesarios
para que, al pulsar la tecla A, no sólo se inicie la partida sino que también comience la reproducción
de la melodía de juego. Con ese propósito, debemos generar sucesivamente las diferentes ondas
cuadradas con la frecuencia y la duración correspondiente según las notas que componen la
melodía. En este sentido, para poder establecer una determinada frecuencia será necesario
configurar convenientemente uno de los timers disponibles. Por otro lado, aprovecharemos las
propias interrupciones para medir la duración de cada una de las notas.
Igualmente, debemos garantizar que la melodía de juego pueda escucharse durante toda la
partida. De este modo, si se agota la melodía antes de que finalice la partida, debemos volver a
reproducirla desde el principio.
Es importante verificar que las melodías suenan correctamente, que las frecuencias generadas
son correctas (frecuencia y duración correspondiente a cada nota medidas con el osciloscopio) y que
se puede controlar el volumen de reproducción para no molestar al resto de los alumnos.
8.1.6 Hito 5: Sistema final
Objetos implicados: Todos.
8.1.6.1 Sesión 9
En esta sesión se debe completar el prototipo básico completo: hay que incluir el cálculo y
visualización de resultados, y la gestión de los 3 niveles de dificultad.
El plan de pruebas del prototipo final debe ser definido por el alumno y presentado en la
memoria final.
57
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
8.1.6.2
Sesión 10
Durante esta sesión está prevista la realización opcional de mejoras.
Es importante que no se deje para el final la redacción completa de la memoria, sino que se
vaya escribiendo conforme se van construyendo y probando los diferentes subsistemas.
9. Mejoras con puntuación predefinida
Se trata de modificaciones sobre las especificaciones básicas que pueden permitir al alumno
alcanzar una calificación superior a 8 puntos si se realiza en C y 8,5 puntos si se realiza en
ensamblador en el LSED. En este apartado se incluyen algunas mejoras con una indicación sobre
la máxima calificación que se podría obtener en cada una de ellas.
9.1 Estadísticas de juego (máximo 0,3 puntos)
Para la realización de esta mejora se propone la ampliación de la funcionalidad del módulo de
resultados para que, además del total de líneas completadas, muestre también el tiempo o la
duración del juego y la relación entre ambos (i.e. número de líneas completadas por segundo).
Adicionalmente, se mostrará información acerca del número de “Tetris” conseguidos (i.e. conseguir
completar 4 líneas simultáneamente).
Dificultad estimada: BAJA.
9.2 Generación aleatoria de piezas (máximo 0,3 puntos)
Esta mejora consistirá en conseguir que la decisión en cuanto a qué nueva pieza debe
incorporarse al juego tenga un carácter aleatorio, tal y como ocurre con la versión real del juego.
Para ello podrá basarse en la oportuna lectura de los 3 primeros bits del registro TCN asociado a
alguno de los temporizadores empleados en la práctica.
Dificultad estimada: BAJA.
9.3 Generar la señal de cada nota mediante el DAC de la
plataforma ENT2004CF (máximo 0,5 puntos)
En esta mejora se propone al alumno que genere las señales asociadas a las notas utilizando el
conversor digital-analógico disponible en la plataforma ENT2004CF. Importante: esta mejora no
exime de la implementación estándar propuesta basada en el empleo de un timer. Mediante
este conversor se puede generar una señal con la forma de onda deseada. Los aspectos más
importantes a considerar en esta mejora son los siguientes:
•
Se recomienda a los alumnos que quieran afrontar esta mejora que realicen los tutoriales
del capítulo 8 del libro [3].
•
Para generar señales de diferentes frecuencias es posible generar un período de la señal
con un conjunto muy elevado de valores (gran resolución) que permita simular las
diferentes frecuencias sin más que ir presentando una y otras muestras de la señal sin
58
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
modificar el intervalo de tiempo entre presentaciones. Para la realización de esta mejora
se sugiere al alumno la consulta de [15].
•
Es importante no olvidar el filtrado posterior de la señal de salida para eliminar el ruido
de la conversión digital analógica (similar al propuesto en la práctica básica).
•
Hay que prestar especial atención a los niveles de tensión de salida del DAC con el fin de
ver si es necesario hacer alguna adaptación de niveles antes de filtrar la señal y de excitar
el amplificador de potencia (módulo final antes de excitar al altavoz).
Dificultad estimada: MEDIA.
9.4 Construcción de un prototipo del HW en PCB (máximo 0,5
puntos)
En la realización de esta mejora es obligatorio utilizar un programa comercial para el diseño de
la PCB. Remitimos al alumno interesado a lo que se comenta en el enunciado y la página web de la
asignatura LCEL, destacando que esta mejora es más asequible en LSED porque el circuito a
diseñar y construir es más pequeño.
Dificultad estimada: MEDIA.
10. Otras Mejoras
Las sugerencias recogidas en este apartado tienen un carácter meramente orientativo. En todo
caso, la calificación dependerá de factores como la originalidad y calidad del trabajo. Todas las
mejoras propuestas (y las que puedan surgir por iniciativa del alumno) podrán llevarse a cabo de
diversas maneras y con distintos grados de perfección y dificultad (de diseño y de implementación),
por lo que la dificultad que se estima es meramente orientativa.
Salvo que se diga lo contrario, las mejoras no eximen de realizar la práctica básica tal cual está
definida en este enunciado, sino que deben ser complementos o programas adicionales.
Para conocer detalles adicionales sobre la implementación o la dificultad de estas u otras
mejoras, no dude en ponerse en contacto con el coordinador del LSED o con cualquiera de los
profesores de la asignatura.
10.1 Velocidad o ritmo de caída variable: nivel de dificultad
incremental
En este caso se propone que la caída de las piezas se acelere progresivamente en la medida en
que el jugador vaya completando un número determinado de líneas. Una posible implementación
puede consistir en definir un ritmo inicial que tras la sucesiva consecución de grupos de 10 o 20
líneas vaya incrementándose, por ejemplo, en un 10%.
Dificultad estimada: BAJA.
59
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
10.2 Ampliación de la funcionalidad por SW
Es posible añadir nuevas posibilidades al sistema:
•
Posibilidad de reproducir nuevas melodías.
•
Posibilidad de subir o bajar una octava toda la canción, o incrementar o decrementar
linealmente la velocidad media de reproducción según el nivel de dificultad elegido. Si se
opta por esta última opción, modificar la duración de las notas de la melodía en
consonancia con la mayor o menor dificultad del juego, entonces debe ralentizarse
proporcionalmente (i.e. linealmente) cada nota, de tal manera que sólo se cambie el ritmo
general de la melodía, no la melodía en sí.
•
Posibilidad de reproducir durante el menú una melodía distinta a la de juego.
•
...
Dificultad estimada: BAJA.
10.3 Perfil de jugador
Esta mejora consiste en añadir al sistema la posibilidad de poder gestionar diferentes perfiles de
jugador. El perfil contendría información específica de cada jugador como su nombre o diferentes
estadísticas de juego. El sistema debería permitir introducir un nombre o identificador con el que
poder referirnos a un perfil determinado. Este es un aspecto importante para esta mejora ya que
supone la implementación de un teclado multi-tecla similar al de los teléfonos móviles. De este
modo, antes de dar comienzo al juego, el sistema podría presentar por pantalla un menú en el que
aparezcan, entre otras, las siguientes opciones:
•
“Seleccionar perfil”, para la selección de un perfil concreto de entre todos los disponibles
en el sistema.
•
“Crear perfil”, que debe permitir la introducción de un nuevo perfil.
•
“Borrar perfil”, para el borrado de un perfil existente.
Una vez elegido el perfil con el que se desea hacer uso del juego, el sistema debería recuperar las
estadísticas almacenadas para el jugador correspondiente con el fin de poder actualizarlas
oportunamente a lo largo de las siguientes partidas. Como es lógico, previamente a la selección de
un nuevo perfil se habría almacenado un conjunto de estadísticas correspondientes al último jugador
que hizo uso del sistema.
Al finalizar el juego se presentaría al usuario una pantalla con sus estadísticas, las
correspondientes a la última partida y las de carácter general o ligadas a todas y a cada una de las
partidas que el usuario haya jugado hasta la fecha. Igualmente, y mediante la selección de la entrada
oportuna en el menú mencionado anteriormente (por ejemplo, “Mostrar estadísticas”), dichas
estadísticas también podrán ser presentadas a voluntad del usuario.
60
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Al margen de las anteriormente mencionadas, otras posibles estadísticas que se proponen son las
siguientes:
•
Puntuación total acumulada para cada nivel de dificultad.
•
Máximo número de líneas completadas durante una partida.
•
Máximo número de “Tetris” conseguidos durante una partida.
•
Nivel de dificultad más alto alcanzado durante una partida.
•
Nivel de jugador: en una escala de 1 a 5 estrellas, siendo 5 la máxima puntuación. Cada
nivel de la escala puede corresponderse con un cierto umbral para la media del número de
líneas completadas por partida (i.e. 1-menos de 10, 2-menos de 25, 3-menos de 50, y así
sucesivamente).
La incorporación de todas estas estadísticas abre la posibilidad adicional de incluir “rankings” de
juego en el sistema donde se presentará a aquellos jugadores que hayan conseguido los mejores
resultados para cada una de las diferentes estadísticas.
Dificultad estimada: MEDIA.
10.4 Visualizador de la siguiente pieza
Este visualizador está pensado como un dispositivo HW adicional que permita al jugador saber
cuál va a ser la siguiente pieza que entrará en juego. En principio, podría contemplarse su posible
implementación a partir de un display de 7 segmentos o de una nueva matriz de leds adicional de
dimensiones 4x2. Esta mejora exigiría adaptar el HW básico ya que los terminales necesarios para
manejar el display ya están siendo usados para iluminar la matriz de leds. En ese sentido, es posible
que necesite hacer uso de un decodificador.
En caso de optar por la alternativa SW de presentar dicha información directamente por la
pantalla del PC, la mejora sería considerada de dificultad menor.
Dificultad estimada: MEDIA-BAJA.
10.5 Sistema de puntuación avanzado
Para llevar a cabo esta mejora será necesario definir una puntuación básica para cada línea
completada. Basándonos en esa idea, permitiremos al usuario mejorar la puntuación final obtenida
al conseguir completar varias líneas simultáneamente (es posible completar a la vez hasta 4 líneas,
jugada que se denomina “Tetris”). De este modo, y en la medida en que el jugador vaya
consiguiendo completar simultáneamente grupos de 2, 3 o 4 líneas, el jugador conseguirá
incrementar el coeficiente por el que se multiplican los puntos ganados por cada una de ellas (x2, x3
y hasta x4).
Dificultad estimada: BAJA.
61
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
10.6 Comienzo de juego con bloques fijos
En esta ocasión se propone la implementación de un modo de juego extra en el que, al comenzar
la partida, el área de juego ya se encuentre parcialmente ocupada por unos “bloques” fijos que
podremos hacer desaparecer a medida que vayamos rellenando líneas con ellos. Se valorará
especialmente la aleatoriedad en cuanto al número y disposición de los bloques mencionados.
Dificultad estimada: MEDIA-BAJA.
10.7 Ampliación del subsistema de visualización
Utilización del LCD (Liquid Cristal Display) de la placa TL04 en lugar de la pantalla del
ordenador para mostrar mensajes y/o la siguiente pieza. En caso de emplear el LCD para la
visualización del área de juego esta mejora supondría desarrollar un segundo programa (no
exime de implementar la versión básica con HW basado en leds). Si sólo se emplea para mostrar
mensajes, hay que adaptar el HW básico porque los terminales usados para manejar el LCD están
siendo usados para iluminar los leds.
Un ejemplo de utilización del LCD se puede consultar en el ejemplo “teclado_lcd.asm” que se
muestra en el tutorial de manejo de la placa TL04 (capítulo 7 de [3]).
Se valorarán detalles como:
•
Incluir símbolos especiales desarrollados por el alumno empleando las posibilidades que
ofrece el LCD (para poder mostrar 3 columnas de notas con LCD de 2 líneas).
•
Implementar una barra de desplazamiento (scroll) por medio de un búfer que guarde las
últimas líneas impresas (el LCD sólo puede mostrar a la vez 2 líneas de texto).
•
HW añadido.
Dificultad estimada: MEDIA-ALTA.
10.8 Comunicación serie utilizando la UART
En este caso se propone utilizar alguna de las UARTs disponibles en el ColdFire para comunicar
un ordenador con el ColdFire a través del puerto serie asíncrono RS-232. Para ello debemos
programar adecuadamente el puerto serie del MCF5272 siguiendo los manuales del fabricante, y
conectar los puertos serie de ambos sistemas digitales mediante un cable de módem nulo. A los
alumnos que lo soliciten los profesores ofrecerán un breve tutorial para el manejo de la UART.
Dificultad estimada: MEDIA-BAJA.
10.9 Conexión con un servidor TFTP
Esta mejora implica la programación del módulo Ethernet del MCF5272. Los profesores
ofrecerán un tutorial y unos programas de ejemplo para el manejo de este módulo. Dado que los
ejemplos están desarrollados en C, esta mejora se recomienda principalmente a aquellos alumnos
que hagan la práctica en C. Un ejemplo de aplicación podría ser la implementación del juego en red.
Dificultad estimada: MEDIA.
62
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
10.10
Recepción de melodías por SMS
En este caso se debe utilizar un módulo GSM utilizando comandos AT que se envían desde el
MCF5272 mediante una comunicación serie (utilizando la UART). Para la realización de esta
mejora los profesores ofrecerán tanto el módulo GSM como un tutorial sobre su manejo mediante
comandos AT.
Dificultad estimada: MEDIA-BAJA.
10.11
Control del juego por medio de un acelerómetro
Los acelerómetros ADXL320, ADXL321 ó ADXL322 proporcionan una tensión proporcional a
la aceleración a la que se encuentra sometido el circuito en cada uno de los 3 ejes espaciales X, Y y
Z. Empleando el convertidor ADC es posible leer esas tensiones y detectar que se producido un
movimiento en el circuito y sustituir las pulsaciones del teclado por movimientos del acelerómetro.
Para esta mejora se valorará especialmente su realización en PCB.
Dificultad estimada: MEDIA-ALTA.
10.12
Reproducción de voz
Utilizando el convertidor D/A de la ENT20004CF (mientras no se está reproduciendo la
melodía) se pueden reproducir algunos mensajes orales, por ejemplo:
•
Menú: “A continuación elija el nivel de dificultad con el que le gustaría jugar: pulse uno
para nivel ‘Fácil’, pulse dos para nivel ‘Medio’...”.
•
Nivel de dificultad seleccionado: “Ha elegido jugar en el nivel...”.
Para guardar dichos mensajes se puede emplear la memoria DRAM disponible en el sistema.
Dificultad estimada: MEDIA-BAJA.
10.13
Reconocimiento de voz
Esta mejora precisa del empleo de HW externo de entrada de audio (etapa de adaptación de
niveles e impedancias, filtro paso bajo antialiasing...). La aplicación consistiría en ordenar por voz
las opciones del menú.
Según el interés mostrado por los alumnos, a lo largo del curso se proporcionarán una o más
clases de orientación e introducción al tema, creándose una lista de distribución de correo
electrónico para las personas interesadas.
Dificultad estimada: ALTA.
10.14
Programación (mediante comunicación serie) de un
kit de reproducción mp3
En este caso se propone utilizar alguna de las UARTs disponibles en el ColdFire para programar
un reproductor de música mp3 a través de comandos AT enviados por una comunicación serie.
63
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
Para abordar esta mejora es conveniente ponerse en contacto con el coordinador de la asignatura
que facilitará el kit de reproducción mp3, una memoria Compact Flash y un grabador de memoria
para cargar las canciones que se desea reproducir. Se puede utilizar para la reproducción de
melodías, incluso mientras se está mostrando el menú o al final del juego.
Dificultad estimada: MEDIA –BAJA.
10.15
Comunicación con una PSP, con una PDA o un iPod
En este caso se propone utilizar alguna de las UARTs disponibles en el ColdFire para
comunicarse con una PSP, con un iPod o con una PDA (quizá con módulo GPS). El material
necesario para realizar esta mejora será facilitado por los profesores.
Dificultad estimada: ALTA.
10.16
Implementación de otros juegos
En este caso se propone aprovechar el HW de presentación desarrollado para la implementación
de algún otro tipo de juego (e.g. un “Pong”, http://es.wikipedia.org/wiki/Pong). Se valorará tanto la
complejidad como la originalidad del juego implementado.
Dificultad estimada: ALTA.
11. Evaluación
Como ya se indicó en la introducción, salvo que se haya indicado lo contrario, la práctica
estándar propuesta contiene las especificaciones mínimas obligatorias que deben cumplir los
sistemas y serán valoradas con un máximo de 8 puntos si se realiza en C y 8,5 puntos si se realiza
en ensamblador. Esta nota máxima sólo se conseguirá si se cumplen todas las especificaciones,
y la memoria, el código, el hardware y las respuestas en el examen oral son perfectos.
La descripción del sistema de menús de la interfaz de usuario es orientativa, aunque en la
evaluación se valorará la calidad de la interfaz desarrollada y las desviaciones respecto a la interfaz
de este enunciado, deben ser explicadas en la memoria final.
Obsérvese que se podría dar el caso de que suspenda alguien a quien la práctica le funciona, pero
presenta graves deficiencias en los demás apartados; aunque será extremadamente improbable que
esto suceda a una pareja de alumnos que hayan realizado la práctica y la memoria basándose en su
propio esfuerzo y conocimiento; tenga en cuenta que en una práctica docente es tan importante
cómo se hagan las cosas como el hecho mismo de hacerlas.
Además de las especificaciones obligatorias se ofrece al alumno la posibilidad de realizar mejoras con
puntuación máxima definida y otras mejoras con puntuación por determinar.
Sobre las consideraciones éticas del trabajo en el laboratorio, remitimos al alumno a la normativa
de la UPM y al documento publicado sobre la filosofía de los laboratorios LCEL y LSED,
disponible a través del portal de la asignatura. Tenga en cuenta que se aplicarán métodos
automáticos de detección de copias o plagios.
64
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
11.1 Funcionamiento y examen oral (<=4 puntos o <=3,5
puntos)
En este apartado se pueden obtener hasta 4 puntos (si se implementa en ensamblador) o 3,5
puntos (si se implementa en C). Estos puntos provendrán (como máximo) de la comprobación por
parte del profesor de que:
•
el prototipo desarrollado responde completamente a las especificaciones obligatorias
contenidas en este enunciado,
•
el alumno responda correctamente a las preguntas que le formule el profesor durante el
examen oral.
•
la nota obtenida en la revisión intermedia obligatoria. Dicha revisión forma parte de la
evaluación de la asignatura, de acuerdo con el apartado 11 de las normas [1] y el apartado
“Evaluación” del programa de la asignatura. La nota máxima en esa prueba es 0,6 puntos,
que forman parte de los 4 o 4,5 puntos que se pueden obtener, como máximo, por
“Funcionamiento y examen oral”. La calificación obtenida será comunicada al realizar el
examen oral final.
Se recuerda que para aprobar el examen oral es necesario un buen dominio individual del
depurador del EDColdFire (cargar, ejecutar y parar un programa, establecer puntos de parada,
visualizar variables o zonas de memoria, realizar modificaciones sobre un programa, etc.) de
acuerdo con lo publicado en el documento de “Principios y valores” [2], especialmente en el
apartado 4.4, aplicable tanto a C como a ensamblador.
11.2 Memoria final (<=1,5 puntos)
La memoria final puede suponer hasta 1,5 puntos de la nota final:
•
la calidad de la redacción, la estructuración y la presentación del documento
•
las justificaciones técnicas de los valores y decisiones adoptados,
•
la claridad y la completitud en las explicaciones técnicas de cada uno de los módulos HW
o SW
•
etc.
11.3 Calidad del SW (<=2,5 puntos)
La calidad del SW desarrollado, explicado y documentado puntuará hasta 2,5 puntos:
•
La estructura general del programa en ensamblador debe responder a lo comentado en
la sección 4.1.2 de [5].
•
Cada subrutina debería tener un único punto de comienzo y un único punto de
terminación, y no debería entrelazarse con otras subrutinas (según se comenta en el
documento “Dudas y preguntas frecuentes del LSED”). Sí que es conveniente que las
65
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
rutinas se aniden (una rutina llame a otra para realizar una cierto cálculo y al terminarse
la segunda rutina, pueda continuar la ejecución de la primera).
•
Debería emplear un buen número de rutinas (subrutinas, métodos o funciones), que le
ayuden a dividir cada problema en subproblemas, y que no resulten muy extensas (y por
lo tanto difíciles de entender y depurar). Algunas rutinas recomendadas se han ido
incluyendo a lo largo de este enunciado. Si pensamos en una media de casi 3 métodos por
objeto, 25 rutinas parece un número mínimo exigible para esta práctica.
•
Debe emplear constantes EQU o #define que permitan reconfigurar fácilmente el
sistema (las instrucciones deberían no usar números mágicos). Ejemplos típicos podrían
ser:
o Una constante que permita fácilmente variar la frecuencia de las interrupciones
temporizadas (FREQ_INT EQU ... o bien #define FREQ_INT...) .
o Una constante para modificar el retardo antirrebotes del teclado (RET_REBOT
EQU... o bien #define RET_REBOT...).
•
Debe emplear modos de direccionamiento variados y apropiados (indexado, indirecto,
post-incremento...) y usar estructuras de datos que agrupen datos interrelacionados y que
faciliten la implementación (búferes, tablas de valores...). Emplear estas técnicas suele
producir código más compacto y elegante, evitándose frecuentemente el abuso de la
desaconsejable técnica de “copiar, pegar y modificar”.
•
Debe incluir comentarios orientativos en el código (comentarios que aporten
información al que los lea, no que se limiten a parafrasear el código). Un ejemplo
paradigmático de un mal comentario es:
o ADD.L #1,D0 * incrementa el registro D0
•
Debe emplear typedef, struct, switch para producir soluciones elegantes, en C. Por cada
objeto debería haber al menos un typedef y un struct. Por ejemplo:
typedef struct {
WORD frecuencias[MAX_NUM_NOTAS];
WORD duraciones[MAX_NUM_NOTAS];
...
} Tmelodia;
typedef struct {
Tmelodia melodias[MAX_NUM_MELODIAS];
...
} Tmelodias;
•
Un empleo abundante y adecuado de #include para dividir el código en subsistemas
coherentes, en C. Al menos debería haber al menos un #include por objeto.
•
Debe emplear pocas variables globales, sobre todo en C. Sólo parece haber 4 objetos
globales: estado, relojes, puerto y resultados. Para minimizar las variables globales debe:
o usar variables static locales a los métodos o funciones en C, para que esas
variables sólo puedan ser usadas por ese método, pero no sean variables locales
66
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
que se pierdan al terminar la ejecución de la rutina, y que así en la siguiente
ejecución de la rutina, mantengan el valor que tenían al acabar la anterior
ejecución:
void rutinaInterrupcionConStaticLocal()
{
static Tmelodias melodias=...;
...
}
o pasar parámetros a los métodos o funciones en C: por valor (si el parámetro no va
a ser variado por la rutina) o por referencia (en caso contrario):
rutinaCopiaParam(int paramPorValor,int *paramPorRefer)
{
* parametroPorReferencia= parametroPorValor;
...
}
•
El empleo de punteros y arrays en C es recomendable para acceder a estructuras de datos
complejas de una manera elegante. Por ejemplo, los arrays de frecuencias y duraciones
antes mostrados en la Tabla 1.
•
No se debe emplear goto, en C.
•
Etc.
11.4 Calidad del HW (<=0,5 puntos)
La calidad del HW básico puede puntuar un máximo de 0,5 puntos:
•
estructura,
•
niveles de ruido presentes, etc.
12. Matrículas y diplomas de honor
De acuerdo con la legislación vigente, en esta asignatura sólo se pueden asignar hasta un 5% de
matrículas de honor. Como habitualmente el número de prácticas destacadas del LSED supera este
límite legal tan estricto, se podrían conceder hasta 7 diplomas de honor a las mejores prácticas (o
aspectos de una práctica) de alumnos que no obtengan matrícula de honor:
•
Diploma de honor por lo innovador que fue el sistema desarrollado.
•
Diploma de honor por la excelente calidad del código escrito en C.
•
Diploma de honor por la excelente calidad del código escrito en ensamblador.
•
Diploma de honor por lo innovadora que fue una de sus mejoras.
•
Diploma de honor por la excelente calidad del subsistema hardware.
•
Diploma de honor por la excelente calidad de la memoria presentada.
67
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
•
Diploma de honor por la calidad del vídeo explicativo del sistema desarrollado.
Este año además se podrá optar a diploma en dos nuevas categorías relacionadas con prácticas
que incorporen en modo alguno algún dispositivo móvil tipo Iphone/Ipod Touch/Móvil Android:
•
Diploma de honor por lo innovador que fue el sistema/aplicación desarrollado con
dispositivos móviles.
•
Diploma de honor por el excelente uso de las posibilidades/recursos ofrecidos por los
dispositivos móviles (ej.: acelerómetros, GPS, brújula, etc.).
A las prácticas que opten a matrícula de honor o a alguno de los diplomas (a excepción de las
categorías relacionadas con la calidad SW y calidad de la memoria), se les pedirá que graben uno o
varios vídeos explicativos de su práctica. Estos vídeos podrían ser incluidos en el canal de la
asignatura en YouTube, si los alumnos implicados no se oponen a su difusión por este medio. El
Departamento dispone de un par de cámaras con capacidad para grabar vídeos, que pueden ser
usadas en el B-043.
Los alumnos que reciban estas matrículas y diplomas tendrán prioridad en la concesión de
Proyectos Fin de Carrera en el Departamento de Ingeniería Electrónica.
La ceremonia de entrega de los Diplomas de Honor tendrá lugar en acto público celebrado en el
Salón de Grados de la ETSIT. Durante la misma, se proyectará un vídeo-resumen que recoja las
mejores prácticas del laboratorio.
13. Bibliografía
[1] Información general del Laboratorio de Sistemas Electrónicos Digitales (LSED).
 http://neirol.die.upm.es/~profes/lsed/0910/public/docs/infolab-lsed0910_v1_0.pdf
[2] Principios, valores, objetivos y aspectos éticos del LCEL y el LSED.
 http://lsed.die.upm.es/public/docs/MetaLaborariosLCELLSED.pdf
[3] R. San Segundo et al, “Introducción a los Sistemas Digitales con el microcontrolador MCF5272”,
Ed. Marcombo S.A., 2006a.
 Básico para el desarrollo de la práctica del MCF5272, dado que describe varios
tutoriales para el manejo de los principales recursos de la plataforma ENT2004CF.
[4] R. San Segundo et al, “Entorno de desarrollo EDColdFire V3.0” Ed. ETSIT, 2006.
 Básico para el desarrollo de la práctica del MCF5272, dado que describe el manejo del
programa EDColdFire y contiene ejemplos sencillos para el manejo de la plataforma
ENT2005CF.
 http://lsed.die.upm.es/public/docs/tutorialBasicoEDColdFire_v7.htm
 http://lsed.die.upm.es/public/docs/EDColdFire_ayuda.htm
68
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
[5] Javier Ferreiros et al, “Aspectos Prácticos de Diseño y Medida en Laboratorios de Electrónica”,
Ed. ETSIT. 2002
 Básico para el desarrollo de la práctica (sobre todo, el capítulo 4).
[6] J.M. Montero et al. “How-To de los equipos del laboratorio” Disponible en Internet a través de
http://lsed.die.upm.es/ 2006.
 Básico para el desarrollo del HW.
 http://lsed.die.upm.es/
[7] J.M Montero et al. “Dudas y preguntas frecuentes del LSED” Disponible en Internet a través del
portal del LSED http://lsed.die.upm.es/ 2006.
[8] J.M Montero et al. “Dudas y preguntas frecuentes del LSED Programación en C”.
 Especialmente útiles en las primeras fases del desarrollo.
 http://lsed.die.upm.es/
[9] C. Carreras et al “Sistemas Electrónicos Digitales” Ed. ETSIT. 2005
[10]
Manuales del MCF5272 de Freescale.
 Sobre todo si se implementa en lenguaje ensamblador o se usan recursos para los cuales
no hay tutoriales disponibles
[11]
J.M Montero et al. “Transparencias sobre programación en C para alumnos de Java”.
 Sobre todo si se carece de experiencia en lenguaje C.
 http://lsed.die.upm.es/
Básicos para el desarrollo del HW:
[12]
“Hojas de características del 74HC244”.
 http://lsed.die.upm.es/
[13]
“Hojas de características del amplificador LM386”.
 http://lsed.die.upm.es/
[14] Enunciado de la Práctica del Laboratorio de Circuitos Electrónicos (LCEL), Curso 2007-2008,
“Sistema de Comunicación Vocal por Modulación de Amplitud”.
 http://neirol.die.upm.es/~profes/lcel/0708/public/docs/enunciado0708-1.0.pdf
[15] Enunciado de la práctica estándar del Laboratorio de Sistemas Electrónicos Digitales (LSED),
Curso 2008-2009, “Piano Hero: un juego musical basadoen el MCF5272”.
 http://neirol.die.upm.es/~profes/lsed/0809/public/docs/Enunciado_lsed0809-v1_4.pdf
[16]
David Brown “Objects in Plain English” Ed Wiley & Sons, 1998
69
COLDTRIX: UN ROMPECABEZAS BASADO EN EL MCF5272
 Documento riguroso y ameno, que compendia las metodologías expuestas por diversos
expertos en el análisis y en el diseño orientado a objetos.
[17]
Plantillas para la creación de un nuevo archivo .c o de un nuevo archivo .h.
 http://lsed.die.upm.es/public/sw/objeto.c
 http://lsed.die.upm.es/public/sw/objeto.h
[18]
Esquemas de salida y entrada del entrenador.
 http://lsed.die.upm.es/public/docs/salidasEntrenador.jpg
 http://lsed.die.upm.es/public/docs/salidasEntrenador.jpg
[19]
Fotos sobre cómo conectar el HW de la práctica a la placa TL04.
 http://lsed.die.upm.es/public/fotos/hw1.jpg
 http://lsed.die.upm.es/public/fotos/hw2.jpg
[20] The C book, online version of The C Book, second edition by Mike Banahan, Declan Brady and
Mark Doran, originally published by Addison Wesley in 1991 (freely available).
 http://publications.gbdirect.co.uk/c_book/
[21] Implementación en C incompleta (pero funcional) de la función printf, adaptada al EdColdFire
por Víctor Miguel Morales.
 http://lsed.die.upm.es/public/sw/printf.zip
Esta bibliografía se puede encontrar fácilmente en Publicaciones de la ETSI Telecomunicación
de la UPM, en su biblioteca o ciberteca, o en el laboratorio B-043.
70

Documentos relacionados