Descarga la aplicación para disfrutar aún más
Esta es una vista previa del archivo. Inicie sesión para ver el archivo original
/** @file SimIntegrador3.c * * @date 16 de noviembre de 2019 * @version 1.0 * * @authors Vazquez Saraullo, Federico Alejandro. * * @brief Archivo fuente que simula a los puertos 0x400, 0x600 y 0x700, y se * utiliza para validar el programa del ejercicio 3 de los * integradores. Los resultados esperados son: * * Sala Cantidad de movimientos * 0 1 * 1 0 * 2 0 * 3 6 * 4 0 * 5 5 * 6 0 * 7 4 * * Sala/s en las que se detectó movimiento durante más de un minuto * consecutivo: Sala 3. * * El orden en que se reciben los datos de las salas es: Sala 7(x4), * Sala 3(x6), Sala 5(x2), Sala 0 y Sala 5(x3). * * @note Solo se pueden habilitar los puertos con dirección 0x400, 0x600 y * 0x700. Los demás puertos se toman como que no están disponibles en la * PC. */ /** \addtogroup Simulador para ejercicio 3 de los integradores. * @{ */ /*==================[inclusiones]============================================*/ #include <stdio.h> /*==================[macros]=================================================*/ /** @def PUERTO_BASE1 * @brief Dirección base del puerto 0x400 disponible según este simulador.*/ #define PUERTO_BASE1 0x400 /** @def PUERTO_BASE2 * @brief Dirección base del puerto 0x600 disponible según este simulador.*/ #define PUERTO_BASE2 0x600 /** @def PUERTO_BASE3 * @brief Dirección base del puerto 0x700 disponible según este simulador.*/ #define PUERTO_BASE3 0x700 /** @def CANT_CAMARAS * @brief Cantidad total de cámaras en el museo.*/ #define CANT_CAMARAS 8 /** @def CANT_ELEM_VEC(x) * @brief Macro para calcular la cantidad de elementos de un vector "X".*/ #define CANT_ELEM_VEC(x) (sizeof(x) / sizeof(x[0])) /*==============================[Tipos de datos]=============================*/ typedef enum{ FIN_OFF, FIN_ON }finStatus_t; typedef enum{ SINC_EQUAL_00, SINC_NOT_EQUAL_01, SINC_NOT_EQUAL_10, SINC_EQUAL_11 }sincStatus_t; typedef enum{ SALA0, SALA1, SALA2, SALA3, SALA4, SALA5, SALA6, SALA7 }numSa_t; typedef enum{ DESHABILITADO, HABILITADO, ERROR_ESTADO }portStatus_t; typedef struct{ unsigned int dir; portStatus_t estado; }puerto_t; typedef enum{ OK, ERROR1, ERROR2, ERROR3 }estadoActivacion_t; /*==================[declaración de variables internas]======================*/ /**@var dirPuertos * @brief Vector que almacena la dirección y estado de los puertos, los cuales * están inicialmente deshabilitados.*/ static puerto_t dirPuertos[] = { { .dir = PUERTO_BASE1, .estado = DESHABILITADO}, { .dir = PUERTO_BASE2, .estado = DESHABILITADO}, { .dir = PUERTO_BASE3, .estado = DESHABILITADO} }; /*==================[definición de funciones internas]=======================*/ /** @fn unsigned char ArmarDatoPuerto (unsigned int port, numSa_t ns,\ sincStatus_t sinc, finStatus_t fin ) * @brief Permite armar un valor de 8 bits según el puerto que se desea leer. * Se piden los datos de bits de fin, sincronismo y número de sala, * aunque devuelve solo lo necesario para el puerto solicitado. * @return unsigned char Dato armado para ser enviado al puerto. */ unsigned char ArmarDatoPuerto (unsigned int port, numSa_t ns,\ sincStatus_t sinc, finStatus_t fin ) { /* Declaraciones locales */ unsigned char valor; /* Cuerpo de la función*/ switch(port){ case PUERTO_BASE1: valor = (((unsigned int) fin) << 7 ); break; case PUERTO_BASE2: valor = ( ((((unsigned int) sinc) & 0x03) << 5 ) + \ (((unsigned int) ns) & 0x07) ); break; default:valor = 0; } return valor; } /** @fn int BuscarPuerto (puerto_t portVec[], int cnt, unsigned int port) * @brief Permite buscar en forma secuencial la dirección "port" dentro del vector "portVec" el cual tiene "cnt" elementos. * @return int que vale: * -1: No se encontró al "port" en "porVec". * otro valor: Se encontró. */ int BuscarPuerto (puerto_t portVec[], int cnt, unsigned int port) { /* Declaraciones locales */ int i = 0; int pos = -1; /* Cuerpo de la función*/ while(i < cnt && pos == -1){ if(portVec[i].dir == port){ pos = i; } else{ i++; } } return pos; } /** @fn int ioperm (unsigned int port, unsigned int cant, int accion) * @brief Permite habilitar o deshabilitar una cantidad entera de puertos consecutivos. * @return estadoActivacion_t que vale: * OK: Se habilita/deshabilita correctamente. * ERROR1: Error por valores de cant y/o accion. * ERROR2: Error por dirección del puerto. * ERROR3: Error por direcciones consecutivas de puertos. */ int ioperm (unsigned int port, unsigned int cant, int accion) { /* Declaraciones locales */ unsigned int i = 0; int pos; estadoActivacion_t activacion; portStatus_t estadoASetear; /* Cuerpo de la función*/ /*Se guarda el estado a setear. Aunque "estadoASetear" sea enum, admite *valores negativos y mayores a 1.*/ switch(accion){ case 0: estadoASetear = DESHABILITADO; break; case 1: estadoASetear = HABILITADO; break; default: estadoASetear = ERROR_ESTADO; } /*Se validan los parámetros formales.*/ if(cant > 0 && (estadoASetear == HABILITADO || estadoASetear == DESHABILITADO) ){ /*Se hace primero una búsqueda secuencial de la dirección "port" en el *vector "dirPuertos".*/ pos = BuscarPuerto(dirPuertos, CANT_ELEM_VEC(dirPuertos), port); /*Si se encuentra el puerto, se chequea que los puertos consecutivos se *puedan habilitar. Por defecto, se supone que se pueden habilitar hasta *que se demuestre lo contrario.*/ if(pos != -1){ i = 1; activacion = OK; /*Se buscan los puertos consecutivos en el vector "dirPuertos".*/ while(i < cant && activacion == OK){ if((port + i) != dirPuertos[pos + i].dir){ activacion = ERROR3; } else{ i++; } } /*Se habilitan/deshabilitan si es posible.*/ if(activacion == OK){ for (i = 0; i < cant; i++){ dirPuertos[pos + i].estado = estadoASetear; } } } else{ activacion = ERROR2; } } else{ activacion = ERROR1; } return activacion; } /** @fn void MostrarErrorLectura() * @brief Muestra un mensaje de error en caso de que exista uno cuando se usa la función "inb". */ void MostrarErrorLectura() { /* Declaraciones locales */ /* Cuerpo de la función*/ printf("\n\n****************************************************************************************\n"); printf("ERROR. El puerto, por el que desea leer un dato, no existe o no esta habilitado.\n"); printf("****************************************************************************************\n"); } /*Para esta función se consideraron los siguientes casos: * -Datos válidos de salas 0, 3, 5 y 7. * -Poner varios casos para cada valor para así tener en cuenta la posible * doble lectura innecesaria en el programa de aplicación. * -Bits de sincronismo S0 y S1 cambian entre cada dato válido de 00 a 11 y * viceversa; también cambian de 01 a 10 entre cada dato inválido. * -Bit F en 1 durante toda la lectura, hasta que se terminan los datos para * leer, luego es simpre 0. Cuando esto sucede, según el sincronismo el dato * es inválido para que contemplar la situación en la que el alumno piense * que tiene que analizar los bits S0 y S1 antes de ver el bit de fin.*/ unsigned char inb( int port) { /* Declaraciones locales */ static int orden=0; int pos; unsigned char dato = 0; /*Se verifica que el puerto está habilitado*/ pos = BuscarPuerto(dirPuertos, CANT_ELEM_VEC(dirPuertos), port); if( pos == -1 || dirPuertos[pos].estado == DESHABILITADO){ MostrarErrorLectura(); } else{ switch(port) { case PUERTO_BASE2: switch(orden) { case 0: case 1: case 2: case 3: case 4: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 5: case 6: case 7: case 8: case 9: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA7, SINC_EQUAL_00, FIN_ON); break; case 10: case 11: case 12: case 13: case 14: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 15: case 16: case 17: case 18: case 19: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA7, SINC_EQUAL_11, FIN_ON); break; case 20: case 21: case 22: case 23: case 24: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 25: case 26: case 27: case 28: case 29: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA7, SINC_EQUAL_00, FIN_ON); break; case 30: case 31: case 32: case 33: case 34: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 35: case 36: case 37: case 38: case 39: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA7, SINC_EQUAL_11, FIN_ON); break; case 40: case 41: case 42: case 43: case 44: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 45: case 46: case 47: case 48: case 49: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA3, SINC_EQUAL_00, FIN_ON); break; case 50: case 51: case 52: case 53: case 54: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 55: case 56: case 57: case 58: case 59: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA3, SINC_EQUAL_11, FIN_ON); break; case 60: case 61: case 62: case 63: case 64: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 65: case 66: case 67: case 68: case 69: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA3, SINC_EQUAL_00, FIN_ON); break; case 70: case 71: case 72: case 73: case 74: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 75: case 76: case 77: case 78: case 79: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA3, SINC_EQUAL_11, FIN_ON); break; case 80: case 81: case 82: case 83: case 84: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 85: case 86: case 87: case 88: case 89: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA3, SINC_EQUAL_00, FIN_ON); break; case 90: case 91: case 92: case 93: case 94: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 95: case 96: case 97: case 98: case 99: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA3, SINC_EQUAL_11, FIN_ON); break; case 100: case 101: case 102: case 103: case 104: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 105: case 106: case 107: case 108: case 109: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA5, SINC_EQUAL_00, FIN_ON); break; case 110: case 111: case 112: case 113: case 114: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 115: case 116: case 117: case 118: case 119: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA5, SINC_EQUAL_11, FIN_ON); break; case 120: case 121: case 122: case 123: case 124: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 125: case 126: case 127: case 128: case 129: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_EQUAL_00, FIN_ON); break; case 130: case 131: case 132: case 133: case 134: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 135: case 136: case 137: case 138: case 139: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA5, SINC_EQUAL_11, FIN_ON); break; case 140: case 141: case 142: case 143: case 144: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 145: case 146: case 147: case 148: case 149: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA5, SINC_EQUAL_00, FIN_ON); break; case 150: case 151: case 152: case 153: case 154: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 155: case 156: case 157: case 158: case 159: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA5, SINC_EQUAL_11, FIN_ON); break; case 160: case 161: case 162: case 163: case 164: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; default: dato = ArmarDatoPuerto(PUERTO_BASE2, SALA0, SINC_NOT_EQUAL_01, FIN_OFF); } break; case PUERTO_BASE1: switch(orden) { case 0: case 1: case 2: case 3: case 4: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 5: case 6: case 7: case 8: case 9: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA7, SINC_EQUAL_00, FIN_ON); break; case 10: case 11: case 12: case 13: case 14: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 15: case 16: case 17: case 18: case 19: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA7, SINC_EQUAL_11, FIN_ON); break; case 20: case 21: case 22: case 23: case 24: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 25: case 26: case 27: case 28: case 29: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA7, SINC_EQUAL_00, FIN_ON); break; case 30: case 31: case 32: case 33: case 34: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 35: case 36: case 37: case 38: case 39: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA7, SINC_EQUAL_11, FIN_ON); break; case 40: case 41: case 42: case 43: case 44: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 45: case 46: case 47: case 48: case 49: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA3, SINC_EQUAL_00, FIN_ON); break; case 50: case 51: case 52: case 53: case 54: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 55: case 56: case 57: case 58: case 59: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA3, SINC_EQUAL_11, FIN_ON); break; case 60: case 61: case 62: case 63: case 64: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 65: case 66: case 67: case 68: case 69: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA3, SINC_EQUAL_00, FIN_ON); break; case 70: case 71: case 72: case 73: case 74: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 75: case 76: case 77: case 78: case 79: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA3, SINC_EQUAL_11, FIN_ON); break; case 80: case 81: case 82: case 83: case 84: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 85: case 86: case 87: case 88: case 89: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA3, SINC_EQUAL_00, FIN_ON); break; case 90: case 91: case 92: case 93: case 94: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 95: case 96: case 97: case 98: case 99: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA3, SINC_EQUAL_11, FIN_ON); break; case 100: case 101: case 102: case 103: case 104: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 105: case 106: case 107: case 108: case 109: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA5, SINC_EQUAL_00, FIN_ON); break; case 110: case 111: case 112: case 113: case 114: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 115: case 116: case 117: case 118: case 119: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA5, SINC_EQUAL_11, FIN_ON); break; case 120: case 121: case 122: case 123: case 124: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 125: case 126: case 127: case 128: case 129: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_EQUAL_00, FIN_ON); break; case 130: case 131: case 132: case 133: case 134: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 135: case 136: case 137: case 138: case 139: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA5, SINC_EQUAL_11, FIN_ON); break; case 140: case 141: case 142: case 143: case 144: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; case 145: case 146: case 147: case 148: case 149: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA5, SINC_EQUAL_00, FIN_ON); break; case 150: case 151: case 152: case 153: case 154: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_10, FIN_ON); break; case 155: case 156: case 157: case 158: case 159: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA5, SINC_EQUAL_11, FIN_ON); break; case 160: case 161: case 162: case 163: case 164: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_ON); break; default: dato = ArmarDatoPuerto(PUERTO_BASE1, SALA0, SINC_NOT_EQUAL_01, FIN_OFF); } break; default: dato=0; /*En el caso de que existiese otro puerto habilitado, se devuelve 0.*/ break; } orden ++; } return dato; } /** @fn void MostrarErrorEscritura() * @brief Muestra un mensaje de error en caso de que exista uno cuando se usa la función "outb". */ void MostrarErrorEscritura() { /* Declaraciones locales */ /* Cuerpo de la función*/ printf("\n\n****************************************************************************************\n"); printf("ERROR. El puerto, por el que desea enviar un dato, no existe o no esta habilitado.\n"); printf("****************************************************************************************\n"); } void outb ( unsigned char dato, unsigned short int port) { /* Declaraciones locales */ int pos, i; unsigned int mask = 0x080; /* Cuerpo de la función*/ /*Se verifica que el puerto está habilitado*/ pos = BuscarPuerto(dirPuertos, CANT_ELEM_VEC(dirPuertos), port); if( pos == -1 || dirPuertos[pos].estado == DESHABILITADO){ MostrarErrorEscritura(); } else{ if(port == PUERTO_BASE3){ printf("\n\n******************************************************************************"); printf("\nEstado de las camaras:\n\t%4s\t%4s\t%4s\t%4s\t%4s\t%4s\t%4s\t%4s\n\t","CAM7","CAM6","CAM5","CAM4", "CAM3","CAM2","CAM1", "CAM0"); for (i = 0; i < CANT_CAMARAS; i++){ if(dato & mask){ printf("%4s\t", "ON"); } else{ printf("%4s\t", "off"); } mask >>= 1; } printf("\n------------------------------------------------------------------------------"); } } } /** @} doxygen end group definition */ /*==================[fin del archivo]============================================*/
Compartir