pub:psoc_gnome

Ficheros fuente del procesador gnome, configuración y uso

Se debe obtener la plantilla del procesador GNOME para PSOC y el proyecto de ejemplos del siguiente enlace:

Al descargarlo, obtendremos un espacio de trabajo que se deberá cargar en el PSOC Creator. La localización recomendada para el espacio de trabajo es la siguiente:

Documentos/PSoC_Creator/PSOC_GNOME

Posteriormente, abrimos el PSOC creator y abrimos el espacio de trabajo, que se ubicará en la ruta anterior. Al abrirse observamos dos proyectos en el espacio de trabajo.

  • gnome_template: Proyecto de plantilla para desarrollar a partir del mismo el proyecto de la asignatura.
  • gnome_cajas: Proyecto de ejemplo de conteo de cajas de diferente tamaño.

A continuación se describe el contenido y uso general de la plantilla.

Al desplegar el árbol jerárquico de la plantilla podremos observar las siguientes fuentes de código C (además de las que vienen por defecto en un proyecto nuevo):

  • gnome.h, gnome.c: Ficheros principales para la emulación del procesador GNOME. Establece la secuencia de ejecución de operaciones de la FSM.
  • gnome_debug.h y gnome_debug.c: Incluye el código para la depuración del microprocesador.
  • gnome_config.h: Configuración del sistema. Este debería ser el único fichero fuente que el alumno necesitará editar.
  • gnome_execute.h y gnome_execute.c: Especifica cómo se lleva a cabo cada instrucción del conjunto total de instrucciones del procesador GNOME.
  • gnome_inst_decoder.h y gnome_inst_decoder.c: Descodificación de los códigos de instrucción via software.
  • gnome_it.h y gnome_it.c: Código para manejar la interrupción del procesador.
  • gnome_lcd.h y gnome_lcd.c: Manejo de la pantalla LCD I2C compatible con el procesador.
  • gnome_memory.h y gnome_memory.c: Define cómo se llevan a cabo los accesos a memoria del procesador, así como los registros mapeados en memoria de las Vías de 8 bit.
  • gnome_register.h: Estructuras de datos correspondientes a los registros del procesador y el estado de ejecución actual (contexto normal o de interrupción).

El procesador GNOME puede utilizar las siguientes características de forma configurable:

  • Depuración del código de programa a través de un puerto serie virtual.
    • Configuración del número máximo de puntos de ruptura.
  • Procesador:
    • Tamaño de la pila del procesador.
    • Vector de Reset.
    • Vector de Interrupción.
    • Configuración de la instrucción jmpadd para que salte siempre a la página cero o a la página en donde se encuentre el PC en ese instante.
  • Vía 8 bit:
    • Activación de las Vías 8 bit (Hay dos disponibles). La vía 1 debe estar activada siempre.
    • Configuración de la posición de los registros mapeados en memoria para cada Vía.
  • Pantalla LCD I2C:
    • Activación o desactivación de la misma.
    • Mensaje a mostrar en cada línea.
    • Offset del primer número a representar en pantalla (Conexión A del módulo).
    • Offset del segundo número a representar en pantalla (Conexión B del módulo).
    • Selección de la dirección de la pantalla en el bus I2C.

Para modificar la configuración, se debe editar el fichero gnome_config.h, en el que se encuentran las siguientes definiciones:

#ifndef GNOME_CONFIG
#define GNOME_CONFIG
 
#include "project.h"
 
// Debug
#define GNOME_DEBUGGING_ON              0x01
#define GNOME_DEBUGGING_MAX_BREAKPOINTS 0x08
#define GNOME_DEBUG_MAX_BUFFER_LENGTH   15
 
// Procesador
#define GNOME_WORD_SIZE                 0x04    // 4 bits (NO MODIFICAR)
#define GNOME_STACK_SIZE                0x04    // Tamaño de las pilas
#define GNOME_RESET_VECTOR              0x00    // Vector de reset
#define GNOME_IT_VECTOR                 0xE0    // Vector de interrupción
#define GNOME_JMP_ADD_ALWAYS_PAGE_0     0x00    // 0: Salto siempre a la pagina cero (MSB siempre 0).
                                                // 1: Salto en la pagina actual (MSB = PC[7]).
 
// I/O
#define GNOME_VIA1_ACTIVE                0x01    // Via hardware conectada
#define GNOME_VIA1_CONFIG                0x0D    // Registro de configuracion para la Via
#define GNOME_VIA1_PORT0                 0x0E    // Registro mapeado en memoria para el puerto 0
#define GNOME_VIA1_PORT1                 0x0F    // Registro mapeado en memoria para el puerto 1
 
#define GNOME_VIA2_ACTIVE                0x01    // Via hardware conectada
#define GNOME_VIA2_CONFIG                0x0A    // Registro de configuracion para la Via
#define GNOME_VIA2_PORT0                 0x0B    // Registro mapeado en memoria para el puerto 0
#define GNOME_VIA2_PORT1                 0x0C    // Registro mapeado en memoria para el puerto 1
 
#define GNOME_LCD_MODULE_ACTIVE         0x01        // Pantalla LCD activa
#define GNOME_LCD_MODULE_MSG1           "CG: 0x"    // Mensaje 1
#define GNOME_LCD_LINE_OFFSET1          6           // Offset del primer dato (A)
#define GNOME_LCD_MODULE_MSG2           "CP: 0x"    // Mensaje 2
#define GNOME_LCD_LINE_OFFSET2          6           // Offset del primer dato (B)
#define GNOME_LCD_MODULE_I2C_ADDR       0x27        // Dirección I2C de la pantalla
 
#endif

El programa se carga sobre la memoria EEPROM disponible en el PSoC. Para ello, simplemente abriremos el fichero con extensión .cydwr y hacemos click sobre la pestaña EEPROM de la misma.

En esta ventana se puede modificar el contenido de cada una de las celdas de la memoria (que son de 8 bits). Las primeras 240 posiciones corresponden al contenido del programa del procesador GNOME.

Aunque sería posible editar el contenido desde esta misma ventana, se dispone de una utilidad para importar el programa desde archivo. Para ello, se hará clic en Import….

Sin embargo, se nos pide un fichero de tipo .csv y no podemos utilizar directamente el programa tal y como lo obtuvimos para TkGate. Para ello, se dispone la utilidad tkGate2PSOC5 en la máquina virtual dglab. Este es un pequeño script de Terminal que transforma el array de TkGate (Fichero previamente convertido desde el WinTim32) hasta el fichero .csv necesario.

Ejemplo de fichero .v de TkGate con el programa

    8'h00:  mem_rom= 8'h18;   // 	loadd 4b#1000
    8'h01:  mem_rom= 8'h3D;   // 	storerd RD
    8'h02:  mem_rom= 8'h3D;   // 	storerd RD	;definimos P0 como salida y P1 como entrada
    8'h03:  mem_rom= 8'h94;   // 	jmpadd inicont:  mem_rom= 8'h	;mandamos a inicializar los registros 0,1,2,3
    8'h04:  mem_rom= 8'h11;   // inicio:  mem_rom= 8'h	loadd 4b#0001
    8'h05:  mem_rom= 8'h3D;   // 	storerd RD
    8'h06:  mem_rom= 8'h3D;   // 	storerd RD	;(ack1=1)
    8'h07:  mem_rom= 8'h4D;   // sigue:  mem_rom= 8'h	loadrd RD
    8'h08:  mem_rom= 8'h09;   // 	ror
    8'h09:  mem_rom= 8'h02;   // 	skipc
    8'h0A:  mem_rom= 8'h87;   // 	jmpadd sigue	;esperamos a que rq1=1
    8'h0B:  mem_rom= 8'h4F;   // 	loadrd RF
    8'h0C:  mem_rom= 8'h34;   // 	storerd R4
    8'h0D:  mem_rom= 8'h4F;   // 	loadrd RF
    8'h0E:  mem_rom= 8'h35;   // 	storerd R5	;tras mandarlo, guardamos el dato en los registros seleccionados
    8'h0F:  mem_rom= 8'h11;   // 	loadd 4b#0001
    8'h10:  mem_rom= 8'h3D;   // 	storerd RD
    8'h11:  mem_rom= 8'h10;   // 	loadd 4b#0000
    8'h12:  mem_rom= 8'h3D;   // 	storerd RD	;volvemos a poner ack1=0
    8'h13:  mem_rom= 8'h9D;   // 	jmpadd comprobinic	
    8'h14:  mem_rom= 8'h18;   // 	loadd 4d#8
    8'h15:  mem_rom= 8'h31;   // 	storerd R1		
    8'h16:  mem_rom= 8'h10;   // 	loadd 4d#0
    8'h17:  mem_rom= 8'h30;   // 	storerd R0
    8'h18:  mem_rom= 8'h11;   // 	loadd 4d#1
    8'h19:  mem_rom= 8'h32;   // 	storerd R2
    8'h1A:  mem_rom= 8'h10;   // 	loadd 4d#0
    8'h1B:  mem_rom= 8'h33;   // 	storerd R3
    8'h1C:  mem_rom= 8'h84;   // 	jmpadd inicio		;antes tenia puesto rti
    8'h1D:  mem_rom= 8'h44;   // comprobinic:  mem_rom= 8'h	loadrd R4
    8'h1E:  mem_rom= 8'h03;   // 	skipz				;si es cero, sigue esperando a dato valido
    8'h1F:  mem_rom= 8'hA1;   // 	jmpadd ppeq
    ...
    ...
    ...
    ...
    ...
    ...
    ...
    ...
    8'h60:  mem_rom= 8'hE1;   // 	jmpadd bit0g
    8'h61:  mem_rom= 8'h0A;   // bit0g:  mem_rom= 8'h	rol
    8'h62:  mem_rom= 8'hF7;   // 	jmpadd accpgrand
    8'h63:  mem_rom= 8'h14;   // 	loadd 4b#0100
    8'h64:  mem_rom= 8'h3D;   // 	storerd RD
    8'h65:  mem_rom= 8'h3D;   // 	storerd RD
    8'h66:  mem_rom= 8'h40;   // 	loadrd R0
    8'h67:  mem_rom= 8'h3E;   // 	storerd RE
    8'h68:  mem_rom= 8'h41;   // 	loadrd R1
    8'h69:  mem_rom= 8'h3E;   // 	storerd RE
    8'h6A:  mem_rom= 8'h4D;   // espera:  mem_rom= 8'h	loadrd RD
    8'h6B:  mem_rom= 8'h0A;   // 	rol
    8'h6C:  mem_rom= 8'h0A;   // 	rol
    8'h6D:  mem_rom= 8'h02;   // 	skipc
    8'h6E:  mem_rom= 8'hEA;   // 	jmpadd espera	;espera a que se active rq0
    8'h6F:  mem_rom= 8'h10;   // 	loadd 4b#0000
    8'h70:  mem_rom= 8'h3E;   // 	storerd RE
    8'h71:  mem_rom= 8'h3E;   // 	storerd RE
    8'h72:  mem_rom= 8'h14;   // 	loadd 4b#0100
    8'h73:  mem_rom= 8'h3D;   // 	storerd RD
    8'h74:  mem_rom= 8'h10;   // 	loadd 4b#0000
    8'h75:  mem_rom= 8'h3D;   // 	storerd RD
    8'h76:  mem_rom= 8'h84;   // 	jmpadd inicio	
    8'h77:  mem_rom= 8'h14;   // accpgrand:  mem_rom= 8'h	loadd 4b#0100
    8'h78:  mem_rom= 8'h3D;   // 	storerd RD
    8'h79:  mem_rom= 8'h3D;   // 	storerd RD
    8'h7A:  mem_rom= 8'h42;   // 	loadrd R2
    8'h7B:  mem_rom= 8'h3E;   // 	storerd RE
    8'h7C:  mem_rom= 8'h43;   // 	loadrd R3
    8'h7D:  mem_rom= 8'h3E;   // 	storerd RE
    8'h7E:  mem_rom= 8'hEA;   // 	jmpadd espera

Este fichero que contiene el programa, se puede convertir al formato .csv utilizando la siguiente línea de código en el terminal:

tkGate2PSOC5 ruta_al_fichero_de_entrada.v ruta_al_fichero_de_salida.csv

Un ejemplo se muestra en la siguiente imagen:

Al correr el programa se crea el siguiente fichero:

Version, 1
0x18, 0x3d, 0x3d, 0x94, 0x11, 0x3d, 0x3d, 0x4d, 0x09, 0x02, 0x87, 0x4f, 0x34, 0x4f, 0x35, 0x11
0x3d, 0x10, 0x3d, 0x9d, 0x18, 0x31, 0x10, 0x30, 0x11, 0x32, 0x10, 0x33, 0x84, 0x44, 0x03, 0xa1
0x84, 0x45, 0x0a, 0x02, 0xa6, 0xc3, 0x0a, 0x02, 0xe3, 0xaa, 0x0a, 0x02, 0xae, 0xc3, 0x0a, 0x02
0xb2, 0xc3, 0x44, 0x0a, 0x02, 0xb7, 0xc3, 0x0a, 0x02, 0xe3, 0xbb, 0x0a, 0x02, 0xe3, 0xbf, 0x0a
0x02, 0xe3, 0xc3, 0x45, 0x0a, 0x02, 0xc8, 0xf7, 0x0a, 0x02, 0x84, 0xcc, 0x0a, 0x02, 0x84, 0xd0
0x0a, 0x02, 0xd4, 0xf7, 0x44, 0x0a, 0x02, 0x84, 0xd9, 0x0a, 0x02, 0x84, 0xdd, 0x0a, 0x02, 0x84
0xe1, 0x0a, 0xf7, 0x14, 0x3d, 0x3d, 0x40, 0x3e, 0x41, 0x3e, 0x4d, 0x0a, 0x0a, 0x02, 0xea, 0x10
0x3e, 0x3e, 0x14, 0x3d, 0x10, 0x3d, 0x84, 0x14, 0x3d, 0x3d, 0x42, 0x3e, 0x43, 0x3e, 0xea, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Este fichero puede proporcionarse directamente al PSOC Creator para importar los contenidos en la EEPROM.

En el fichero TopDesign.cysch del proyecto plantilla se encuentran dispuestas una serie de elementos que el alumno puede utilizar para el proyecto.

Encontramos 2 vías de 8 bits como interfaz de datos entre el programa del procesador GNOME y la lógica programable.

Cada vía dispone de :

  • 2 Puertos, configurables como entrada o salida.
  • Señales de control para realizar protocolos handshake.
  • Señales de Reset y Reloj del procesador GNOME.

Por otro lado, en la imagen se puede observar resaltado en rojo el conector de la interrupción (ISR). Esta interrupción es la propia del procesador GNOME, y es activa por flanco de subida en la línea de interrupción.

Es muy importante que todos los módulos conserven sus nombres tal y como se muestran en la imagen, puesto que el software hace uso de estos nombres.

La razón por la que todos los módulos tienen sus entradas conectadas a una constante o a un reloj es porque siempre deben estar conectadas a alguna fuente de señal. En caso contrario, el diseño dará un error al comenzar la síntesis de la lógica digital.

En caso de no necesitar la segunda vía, lo recomendable es borrarla, puesto que consume recursos de lógica programable que pueden ser necesarios para completar el proyecto. Siempre debemos asegurarnos de tenerla desactivada en el fichero de configuración o el sistema dará error durante la generación de software.

  • pub/psoc_gnome.txt
  • Última modificación: 2020/09/28 11:44
  • (editor externo)