ServidorTCP.c
1140 lines
| 30.0 KiB
| text/x-c
|
CLexer
r26 | /* | |||
* Servidor.c | ||||
* | ||||
* Created on: Nov 3, 2009 | ||||
* Author: Jose Francisco Quenta | ||||
* | ||||
* Se implementa: | ||||
* -Carga en memoria los apuntes contenidos en un archivo de experimentos: apunte0 -> GPIO | ||||
* -Cambio de apunte. | ||||
* -Lectura del estado actual del apunte y grabado del mismo en un archivo | ||||
r111 | * | |||
* Modified by Iván Manay since Nov 2012 | ||||
* -From UDP to TCP. | ||||
* -Use of a frame for TCP communications with the central control module. | ||||
r26 | */ | |||
#include <stdio.h> | ||||
#include <stdlib.h> | ||||
#include <string.h> | ||||
#include <unistd.h> | ||||
#include <errno.h> | ||||
#include <sys/types.h> | ||||
#include <sys/socket.h> | ||||
#include <netinet/in.h> | ||||
#include <arpa/inet.h> | ||||
#include <netdb.h> | ||||
r116 | #include <time.h> | |||
#include <math.h> | ||||
r26 | ||||
r116 | #include "./Librerias/at91gpio.h" | |||
//#include "./Librerias/Mensajes.h" | ||||
#include "./Librerias/at91adc.h" | ||||
//clock | ||||
#include "./Librerias/at91sysclock.h" | ||||
r26 | ||||
#define PUERTO_SERVIDOR 5500 | ||||
r71 | #define TAM_BUFFER 1024 | |||
r26 | ||||
r130 | #define maskc_out_beam PC30+PC28+PC26+PC24+PC22+PC20 //MSB-UP-LSB MSB-DOWN-LSB //APUNTE | |||
#define maskc_out_cntl PC4+PC5+PC6 //MONITORING CONTROL | ||||
r26 | ||||
r130 | #define mask_sel_canal PC4 //MONITORING CONTROL | |||
#define mask_sel_atenuacion PC5 | ||||
#define mask_sel_calibracion PC6 | ||||
r26 | ||||
r130 | #define maskb_in PB16+PB18+PB20+PB30+PB24+PB22 //MSB-UP-LSB MSB-DOWN-LSB //VERIFICACION | |||
r26 | ||||
r130 | #define maskc_in_adc PC0+PC1 | |||
r26 | ||||
r130 | #define bit_up_2 0x00010000 //Mascara de cada bit a revisar: bit_up_2 es MSB | |||
#define bit_up_1 0x00040000 | ||||
#define bit_up_0 0x00100000 | ||||
#define bit_dow_2 0x40000000 | ||||
#define bit_dow_1 0x01000000 | ||||
#define bit_dow_0 0x00400000 | ||||
#define MyID 11 | ||||
#define MAXPENDING 5 /* Maximum outstanding connection requests */ | ||||
r116 | //parameters for the name of the output file | |||
#define FPRE "AD" //prefix for the output file name | ||||
#define FEXT ".out" //file extension for the output file | ||||
#define FNAMELEN 40 | ||||
//ADC parameters | ||||
#define REP 1 //defines how many times the data acquisation loop is repeated | ||||
r130 | #define NSAMPLES 10 //defines how many samples are taken in one data acqu- | |||
r145 | // isation loop | |||
#define NLOOPS 200 // Number of loops for the transmisor checking | ||||
r116 | #define CNVTIME 14.3 //defines how long it takes to get one sample. Value | |||
// is only needed for the output file, doesn't change | ||||
// any ADC configurations | ||||
#define UREF 3.3 //Reference Voltage of ADC (max. ADC Voltage) | ||||
#define ADCRES 1023 //Resolution of ADC (10bit=1023) | ||||
r26 | char *buff_experimento= NULL; | |||
AT91S_PIO *pioc; | ||||
AT91S_PIO *piob; | ||||
r130 | AT91S_PIO *pio_adc; | |||
AT91S_ADC *padc; | ||||
AT91S_ADC *padd; | ||||
r26 | ||||
r71 | struct control_module_parameters { | |||
char ID[20]; | ||||
char param2[20]; | ||||
char param3[20]; | ||||
char param4[20]; | ||||
}; | ||||
typedef struct control_module_parameters cmp; | ||||
r103 | char *header = NULL; | |||
char *TypeOfInstrument = NULL; | ||||
char *iDSource = NULL; | ||||
char *iDDestino = NULL; | ||||
r111 | char *rx_len = NULL; | |||
r103 | char *cmd = NULL; | |||
char *rx_data = NULL; | ||||
char *crc = NULL; | ||||
r77 | cmp parameters; | |||
r26 | /* | |||
* Zona de declaracion de cabeceras. | ||||
*/ | ||||
r71 | cmp inicializa_modulo(cmp p); | |||
int inicializa_ethernet(); | ||||
int rxData(int, char*); | ||||
void txData(int, char*); | ||||
r26 | void inicializa_gpio(); | |||
r130 | void inicializa_adc(); | |||
r71 | void procesa_peticion(char *rx_buffer, char *tx_buffer); | |||
r26 | int cambia_apuntamiento(char *puntero_char); | |||
int carga_experimento(char *nombre_archivo); | ||||
r103 | char *chequeo_sistema(char *filename, char *numero_muestras); | |||
r71 | void recibe_experimento(char *data, char filename[]); | |||
r103 | void SplitFrame(char *frame); | |||
r111 | void intToStr( int number, char* str ); | |||
r26 | ||||
r116 | //ABS monitoring | |||
r130 | //int ABS_monitoreo(int sel_atenuador, int sel_calibracion, float umbral, int pulsewidth); | |||
char* ABS_monitoreo(int sel_atenuador, int sel_calibracion, float umbral, int pulsewidth); | ||||
r116 | AT91S_ADC * configADC1(void); | |||
AT91S_ADC * configADC2(void); | ||||
FILE * create_Output(char*, time_t); | ||||
void writeOutput(float resultado, FILE * output); | ||||
int checkTx(long int results1[],long int results2[], float umbral, int pulsewidth); | ||||
double mediana(long int *results, unsigned int cuenta); | ||||
float getPhase(long int results1[], long int results2[]); | ||||
int fExists(char *); | ||||
int configCLK(); | ||||
// | ||||
r26 | /* | |||
* | ||||
*/ | ||||
int main(){ | ||||
r71 | int servSocket; | |||
int clntSocket; | ||||
r77 | ||||
r71 | char *rx_buffer = (char *) malloc(TAM_BUFFER); | |||
char *tx_buffer = (char *) malloc(TAM_BUFFER); | ||||
/* Inicializa parametros del modulo*/ | ||||
parameters = inicializa_modulo(parameters); | ||||
r103 | printf("%s\n%s\n%s\n%s\n",parameters.ID, parameters.param2, parameters.param3, parameters.param4); | |||
r71 | /* Inicializa red*/ | |||
servSocket = inicializa_ethernet(); | ||||
/* Inicializamos el puerto GPIO del sistema embebido GSBC-9260S */ | ||||
inicializa_gpio(); | ||||
r130 | inicializa_adc(); | |||
r71 | ||||
while(1){ | ||||
// Recepción TCP de petición | ||||
clntSocket = rxData(servSocket, rx_buffer); | ||||
//testpoint | ||||
printf("rx:%s\n",rx_buffer); | ||||
// Procesamiento de la petición | ||||
procesa_peticion(rx_buffer, tx_buffer); | ||||
//testpoint | ||||
printf("tx:%s\n",tx_buffer); | ||||
// Respuesta del modulo de control | ||||
txData(clntSocket, tx_buffer); | ||||
} | ||||
} | ||||
int inicializa_ethernet(){ | ||||
r26 | struct sockaddr_in inf_servidor; | |||
r71 | int servSocket; | |||
r26 | ||||
r71 | int resultado; | |||
r26 | ||||
r71 | /* Haciendo la estructura local*/ | |||
r26 | memset(&inf_servidor, 0, sizeof(inf_servidor)); | |||
inf_servidor.sin_family= AF_INET; | ||||
inf_servidor.sin_port= htons(PUERTO_SERVIDOR); | ||||
inf_servidor.sin_addr.s_addr= INADDR_ANY; | ||||
/* Se establece el socket */ | ||||
r71 | servSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); | |||
if (servSocket == -1){ | ||||
r116 | printf("No se establecio correctamente el socket: socket()\n"); | |||
//ERROR_FATAL("No se establecio correctamente el socket: socket()\n"); | ||||
r71 | exit(-1); | |||
r26 | } | |||
/* Se asocia el socket a un puerto y una IP */ | ||||
r71 | resultado = bind(servSocket,(struct sockaddr *)&inf_servidor,sizeof(inf_servidor)); | |||
r26 | if (resultado== -1){ | |||
r116 | printf("No se establecio correctamente el socket: bind()\n"); | |||
//ERROR_FATAL("No se establecio correctamente el socket: bind()\n"); | ||||
r71 | exit(-1); | |||
r26 | } | |||
r71 | if (listen(servSocket, MAXPENDING) < 0){ | |||
printf("listen() failed\n"); | ||||
exit(-1); | ||||
} | ||||
r26 | ||||
r71 | return servSocket; | |||
r26 | ||||
r71 | } | |||
r26 | ||||
r71 | int rxData(int servSocket, char* rx_buffer){ | |||
r26 | ||||
r71 | int clntSocket; | |||
struct sockaddr_in inf_cliente; | ||||
int numbytes_recibidos; | ||||
unsigned int inf_client_Len; | ||||
r26 | ||||
r71 | printf("\nEsperando solicitud de cliente...\n"); | |||
r26 | ||||
r71 | /* Set the size of the in-out parameter */ | |||
inf_client_Len = sizeof(inf_cliente); | ||||
/* Se espera hasta que un cliente se conecte */ | ||||
if ((clntSocket = accept(servSocket, (struct sockaddr *) &inf_cliente, | ||||
&inf_client_Len)) < 0) | ||||
printf("accept() failed\n"); | ||||
r26 | ||||
r71 | if ((numbytes_recibidos = recv(clntSocket, rx_buffer, TAM_BUFFER, 0)) < 0) | |||
printf("recv() failed\n"); | ||||
/* Se procede a procesar los datos recibidos */ | ||||
rx_buffer[numbytes_recibidos]= '\0'; | ||||
return clntSocket; | ||||
r26 | } | |||
r71 | void txData(int clntSocket, char* data){ | |||
r26 | ||||
r71 | /* Echo message back to client */ | |||
if (send(clntSocket, data, strlen(data), 0) != strlen(data)) | ||||
printf("send() failed\n"); | ||||
r26 | ||||
r71 | close(clntSocket); /* Close client socket */ | |||
} | ||||
r111 | ||||
r26 | /* | |||
* Esta funcion incializa el puerto GPIO | ||||
*/ | ||||
void inicializa_gpio(){ | ||||
r130 | int desplazamiento_beam[6]={30,28,26,24,22,20}; //Desplazamientos para los pines de apunte | |||
int desplazamiento_cntl[3]={4,5,6}; //Desplazamientos para los pines de control de monitoreo | ||||
unsigned long acumulado_ceros=0; | ||||
int i; | ||||
// Configuracion de los pines de APUNTE y control de monitoreo | ||||
r26 | pioc = pio_map(PIOC_BASE); | |||
r130 | pio_enable(pioc, maskc_out_beam + maskc_out_cntl); | |||
pio_disable_irq(pioc, maskc_out_beam + maskc_out_cntl); | ||||
pio_disable_multiple_driver(pioc, maskc_out_beam + maskc_out_cntl); | ||||
pio_disable_pull_ups(pioc, maskc_out_beam + maskc_out_cntl); | ||||
pio_synchronous_data_output(pioc, maskc_out_beam + maskc_out_cntl); | ||||
pio_output_enable(pioc, maskc_out_beam + maskc_out_cntl); | ||||
r26 | ||||
// Configuracion de los pines de VERIFICACION | ||||
piob = pio_map(PIOB_BASE); | ||||
pio_enable(piob, maskb_in); | ||||
pio_disable_irq(piob, maskb_in); | ||||
pio_disable_multiple_driver(piob, maskb_in); | ||||
pio_disable_pull_ups(piob, maskb_in); | ||||
pio_input_enable(piob, maskb_in); | ||||
r130 | ||||
//Pînes de ADC | ||||
pio_adc = pio_map(PIOC_BASE); | ||||
pin_adc_enable(pio_adc,maskc_in_adc); //Habilitamos PC0 para usar con ADC0 y 1 | ||||
pio_disable_irq(pio_adc, maskc_in_adc); | ||||
pio_disable_multiple_driver(pio_adc, maskc_in_adc); | ||||
pio_disable_pull_ups(pio_adc, maskc_in_adc); | ||||
pio_input_enable(pio_adc, maskc_in_adc); | ||||
//Inicializando a cero los pines de apunte | ||||
for(i=0;i<6;i++) | ||||
acumulado_ceros= acumulado_ceros + (1 << desplazamiento_beam[i]); | ||||
pio_out(pioc, maskc_out_beam, acumulado_ceros, 0); | ||||
//Inicializando a cero los pines de control de monitoreo: atenuacion, calibracion y canal | ||||
for(i=0;i<3;i++) | ||||
acumulado_ceros= acumulado_ceros + (1 << desplazamiento_cntl[i]); | ||||
pio_out(pioc, maskc_out_cntl, acumulado_ceros, 0); | ||||
r26 | } | |||
r130 | void inicializa_adc(){ | |||
r111 | ||||
r130 | if (configCLK() == 1) | |||
printf("clock ADC enable.\n"); | ||||
//configure ADC Settings | ||||
padc=configADC1(); | ||||
padd=configADC2(); | ||||
} | ||||
r26 | /* | |||
r111 | * Divide rx frame into the frame components | |||
r26 | */ | |||
r103 | void SplitFrame(char *frame){ | |||
header = malloc(4); | ||||
*header = *frame; | ||||
*(header + 1) = *(frame + 1); | ||||
*(header + 2) = *(frame + 2); | ||||
*(header + 3) = '\0'; | ||||
TypeOfInstrument = malloc(4); | ||||
*TypeOfInstrument = *(frame + 3); | ||||
*(TypeOfInstrument + 1) = *(frame + 4); | ||||
*(TypeOfInstrument + 2) = *(frame + 5); | ||||
*(TypeOfInstrument + 3) = '\0'; | ||||
iDSource = malloc(8); | ||||
*iDSource = *(frame + 6); | ||||
*(iDSource + 1) = *(frame + 7); | ||||
*(iDSource + 2) = *(frame + 8); | ||||
*(iDSource + 3) = *(frame + 9); | ||||
*(iDSource + 4) = *(frame + 10); | ||||
*(iDSource + 5) = *(frame + 11); | ||||
*(iDSource + 6) = *(frame + 12); | ||||
*(iDSource + 7) = '\0'; | ||||
iDDestino = malloc(8); | ||||
*iDDestino = *(frame + 13); | ||||
*(iDDestino + 1) = *(frame + 14); | ||||
*(iDDestino + 2) = *(frame + 15); | ||||
*(iDDestino + 3) = *(frame + 16); | ||||
*(iDDestino + 4) = *(frame + 17); | ||||
*(iDDestino + 5) = *(frame + 18); | ||||
*(iDDestino + 6) = *(frame + 19); | ||||
*(iDDestino + 7) = '\0'; | ||||
r111 | rx_len = malloc(7); | |||
*rx_len = *(frame + 20); | ||||
*(rx_len + 1) = *(frame + 21); | ||||
*(rx_len + 2) = *(frame + 22); | ||||
*(rx_len + 3) = *(frame + 23); | ||||
*(rx_len + 4) = *(frame + 24); | ||||
*(rx_len + 5) = *(frame + 25); | ||||
*(rx_len + 6) = '\0'; | ||||
r103 | cmd = malloc(5); | |||
*cmd = *(frame + 26); | ||||
*(cmd + 1) = *(frame + 27); | ||||
*(cmd + 2) = *(frame + 28); | ||||
*(cmd + 3) = *(frame + 29); | ||||
*(cmd + 4) = '\0'; | ||||
r111 | int l = atoi(rx_len); | |||
r107 | rx_data = malloc(l + 1); | |||
r103 | int i; | |||
for (i = 30; i < 30 + l; i++) | ||||
*(rx_data + (i-30)) = *(frame + i); | ||||
*(rx_data + l) = '\0'; | ||||
crc = malloc(2); | ||||
*crc = *(frame + 30 + l); | ||||
*(crc + 1) = '\0'; | ||||
} | ||||
r111 | /* | |||
* Esta funcion procesa el mensaje de peticion y genera respuesta | ||||
*/ | ||||
r103 | void procesa_peticion(char *rx_buffer, char *tx_buffer){ | |||
// int n = 0; | ||||
char filename1[50]; | ||||
char filename2[] = "verificacion.txt"; | ||||
char *tx_data = NULL; | ||||
r111 | char *tx_len = NULL; | |||
r103 | SplitFrame(rx_buffer); | |||
if ((cmd == NULL) || (rx_data == NULL)){ | ||||
r116 | printf("procesarPeticion: formato de mensaje incorrecto"); | |||
//ERROR("procesarPeticion: formato de mensaje incorrecto"); | ||||
r26 | } | |||
r103 | else{ | |||
if(strcmp(cmd,"SNDF") == 0){ | ||||
recibe_experimento(rx_data,filename1); | ||||
carga_experimento(filename1); | ||||
cambia_apuntamiento("0"); | ||||
tx_data = (char*)malloc(3); | ||||
tx_data = "OK"; | ||||
} | ||||
else if(strcmp(cmd,"CHGB") == 0){ | ||||
cambia_apuntamiento(rx_data); | ||||
tx_data = (char*)malloc(3); | ||||
tx_data = "OK"; | ||||
} | ||||
else if(strcmp(cmd,"ANST") == 0){ | ||||
tx_data = chequeo_sistema(filename2,rx_data); | ||||
r121 | printf("%s\n",tx_data); | |||
} | ||||
r145 | else if(strcmp(cmd,"BGPH") == 0){ | |||
tx_data = ABS_monitoreo(1, 0, 50, 10); | ||||
r130 | // tx_data = "Not implemented\n"; | |||
r103 | printf("%s\n",tx_data); | |||
} | ||||
r145 | else if(strcmp(cmd,"LWPH") == 0){ | |||
tx_data = ABS_monitoreo(0, 0, 50, 10); | ||||
// tx_data = "Not implemented\n"; | ||||
printf("%s\n",tx_data); | ||||
} | ||||
r111 | else if(strcmp(cmd,"NTST") == 0){ | |||
tx_data = malloc(strlen(parameters.ID) + 1); | ||||
strcpy(tx_data,parameters.ID); | ||||
printf("%s\n",tx_data); | ||||
} | ||||
r103 | else{ | |||
tx_data = (char*)malloc(6); | ||||
tx_data = "Error"; | ||||
r116 | printf("procesa_peticion: comando no reconocido"); | |||
//ERROR("procesa_peticion: comando no reconocido"); | ||||
r103 | } | |||
r111 | tx_len = malloc(7); | |||
int number = strlen(tx_data); | ||||
intToStr(number, tx_len ); | ||||
r103 | strcpy(tx_buffer,header); //3 | |||
strcat(tx_buffer,TypeOfInstrument); //3 | ||||
strcat(tx_buffer,parameters.ID); //7 | ||||
strcat(tx_buffer,iDSource); //7 | ||||
r111 | strcat(tx_buffer,tx_len); //6 | |||
r103 | strcat(tx_buffer,cmd); //4 | |||
r111 | strcat(tx_buffer,tx_data); //? | |||
r103 | strcat(tx_buffer,crc); //1 | |||
} | ||||
r26 | } | |||
r71 | /* | |||
* Esta función genera el archivo de experimento a partir de la trama TCP recibida | ||||
*/ | ||||
void recibe_experimento(char *p_data, char filename[]){ | ||||
FILE *fd; | ||||
int i = 0; | ||||
while (*p_data != '\n'){ | ||||
filename[i] = *p_data; | ||||
i++; | ||||
p_data++; | ||||
} | ||||
filename[i] = '\0'; | ||||
p_data = p_data - i; | ||||
fd = fopen(filename,"w"); | ||||
fprintf(fd, p_data); | ||||
fclose(fd); | ||||
} | ||||
r26 | /* | |||
* Esta funcion carga un archivo en un buffer que esta ubicado en memoria, luego | ||||
* este buffer es usado en la funcion "cambia_apuntamiento" para obtener el dato | ||||
* que sera usado en el cambio de apuntamiento. | ||||
*/ | ||||
int carga_experimento(char *nombre_archivo){ | ||||
FILE *Archivo_Fd; | ||||
char *cadena = (char *) malloc(25); | ||||
int longitud_cadena; | ||||
int num_bytes= 0; | ||||
int num_filas= 0; | ||||
r71 | Archivo_Fd = fopen(nombre_archivo,"r"); // Se procede a abrir el archivo, segun la ruta especificada | |||
r26 | if(!Archivo_Fd){ | |||
r116 | printf("carga_archivo: No se pudo abrir el archivo!!! --> fopen()\n"); | |||
//ERROR("carga_archivo: No se pudo abrir el archivo!!! --> fopen()\n"); | ||||
r26 | return -1; | |||
}else{ | ||||
while(!feof(Archivo_Fd)){ // Se procede a calcular la longitud del archivo para separar memoria | ||||
fgets(cadena,20,Archivo_Fd); | ||||
longitud_cadena= strlen(cadena); | ||||
cadena[longitud_cadena-1] = '\0'; | ||||
num_bytes = num_bytes + longitud_cadena; | ||||
num_filas++; | ||||
} | ||||
rewind(Archivo_Fd); // Se reinicia el puntero del archivo | ||||
char *buffer_temporal = (char *) malloc(num_bytes+1); // Se separa espacio de memoria segun | ||||
// la longitud del archivo | ||||
fread(buffer_temporal, sizeof(char), num_bytes, Archivo_Fd); | ||||
r77 | char *puntero= strstr(buffer_temporal,".ab1"); // Se procede a eliminar la cabecera del archivo | |||
r26 | puntero= puntero + 12; | |||
buff_experimento = (char *) malloc(7*(num_filas-3)); // num_bytes_fila*(num_filas-3); | ||||
strncpy(buff_experimento,puntero,7*(num_filas-3)); // Se carga en memoria la informacion del archivo | ||||
fclose(Archivo_Fd); | ||||
return 1; | ||||
} | ||||
} | ||||
/* | ||||
* Esta funcion recibe un numero en formato char, el dato se transforma a su equivalente en | ||||
* un numero entero, que sera usado para sacar un dato del buffer "buff_experimento", esta | ||||
* dato es el valor que se enviara al sistema de conmutacion RF para el cambio de apunte a | ||||
* traves del puerto GPIO. | ||||
*/ | ||||
int cambia_apuntamiento(char *puntero_char){ | ||||
/*MSB-UP-LSB MSB-DOWN-LSB*/ | ||||
int desplazamiento[6]={30,28,26,24,22,20}; // Defino los dezplazamientos que se aplicara | ||||
// al dato que ingresa para formar el número | ||||
// entero que se le pasara al puerto GPIO | ||||
// Estos números son los pines del puerto GPIO | ||||
// que se estan usando para el control | ||||
int puntero= atoi(puntero_char); // Se convierte a entero la direccion del puntero | ||||
int base= 7*puntero; // base= cantidad_bytes del dato x puntero | ||||
// cantidad de bytes es el numero de bytes que | ||||
r77 | printf("%s\n",puntero_char); // contiene cada dato, para este caso es 7 | |||
r26 | // porque es 6 bits de datos + 1 bit del cambio | |||
// de linea. | ||||
char valor_char; | ||||
unsigned long valor; | ||||
unsigned long acumulado_ceros=0; | ||||
unsigned long acumulado_unos=0; | ||||
int offset; // Defino offset para el desplazamiento a traves | ||||
for(offset=0;offset<6;offset++){ // de cada dato que se obtiene del "buff_experimento" | ||||
r77 | ||||
r26 | valor_char= buff_experimento[base+offset]; // Obtengo el dato | |||
if (valor_char == '0'){ // Obtengo el número acumulado segun sea un cero o un uno | ||||
valor= 0; | ||||
acumulado_ceros= acumulado_ceros + (1 << desplazamiento[offset]); | ||||
}else{ | ||||
valor= 1; | ||||
acumulado_unos= acumulado_unos + (1 << desplazamiento[offset]); | ||||
} | ||||
} | ||||
r130 | pio_out(pioc, maskc_out_beam, acumulado_unos, 1); | |||
pio_out(pioc, maskc_out_beam, acumulado_ceros, 0); | ||||
r26 | ||||
return 1; | ||||
} | ||||
/* | ||||
r103 | * Esta funcion lee "n" veces el estado del APUNTE actual y reporta | |||
* una cadena de Verificacion. | ||||
*/ | ||||
char* chequeo_sistema(char *filename, char *numero_muestras){ | ||||
int i; | ||||
int cnt = 0; | ||||
unsigned int entradac= 0; | ||||
char page0[250]; | ||||
r121 | /*strcpy(page0,"Verificacion\n"); | |||
strcat(page0,parameters.ID);*/ | ||||
strcpy(page0,parameters.ID); | ||||
strcat(page0,"\n-------\n"); | ||||
r103 | ||||
char page1[8]; | ||||
do{ | ||||
//Inicializando arreglo | ||||
for(i=0;i<6;i++) | ||||
page1[i]='0'; | ||||
page1[6] = '\n'; | ||||
page1[7] = '\0'; | ||||
//Lectura de puerto | ||||
entradac= pio_in(piob,maskb_in); | ||||
//Dandole formato al dato | ||||
if (!(entradac & bit_up_2)) | ||||
page1[0] = '1'; | ||||
if (!(entradac & bit_up_1)) | ||||
page1[1] = '1'; | ||||
if (!(entradac & bit_up_0)) | ||||
page1[2] = '1'; | ||||
if (!(entradac & bit_dow_2)) | ||||
page1[3] = '1'; | ||||
if (!(entradac & bit_dow_1)) | ||||
page1[4] = '1'; | ||||
if (!(entradac & bit_dow_0)) | ||||
page1[5] = '1'; | ||||
strcat(page0, page1); | ||||
cnt=cnt+1; | ||||
usleep(1*1000*1000); | ||||
}while(cnt < atoi(numero_muestras)); | ||||
page0[strlen(page0)] = '\0'; | ||||
char *all_pages = malloc(strlen(page0)+1); | ||||
strcpy(all_pages, page0); | ||||
return all_pages; | ||||
} | ||||
r111 | ||||
/* | ||||
* | ||||
*/ | ||||
r71 | cmp inicializa_modulo(cmp p){ | |||
FILE *fd = fopen("configuration.txt","r"); | ||||
fgets(p.ID,20,fd); | ||||
r103 | p.ID[7]='\0'; | |||
r71 | fgets(p.param2,20,fd); | |||
r103 | p.param2[10]='\0'; | |||
r71 | fgets(p.param3,20,fd); | |||
r103 | p.param3[10]='\0'; | |||
r71 | fgets(p.param4,20,fd); | |||
r103 | p.param4[10]='\0'; | |||
r71 | fclose(fd); | |||
return p; | ||||
} | ||||
r111 | ||||
/* | ||||
* | ||||
*/ | ||||
void intToStr( int number, char* str ) | ||||
{ | ||||
int index = 0; | ||||
while( number > 0 ) | ||||
{ | ||||
int digit = number%10; | ||||
str[index++] = digit + '0'; | ||||
number /= 10; | ||||
} | ||||
str[index] = '\0'; | ||||
//Adding zero to the left | ||||
int n= strlen(str); | ||||
if (n == 1) { | ||||
strcat(str,"00000"); | ||||
index = index + 5; | ||||
}else if(n == 2){ | ||||
strcat(str,"0000"); | ||||
index = index + 4; | ||||
}else if(n == 3){ | ||||
strcat(str,"000"); | ||||
index = index + 3; | ||||
}else if(n == 4){ | ||||
strcat(str,"00"); | ||||
index = index + 2; | ||||
}else if(n == 5){ | ||||
strcat(str,"0"); | ||||
index = index + 1; | ||||
} | ||||
//Now reverse the numbers in the string. | ||||
int position; | ||||
for( position = 0; position <= (index-1)/2; ++position ) | ||||
{ | ||||
char tmp = str[position]; | ||||
str[position] = str[(index-1)-position]; | ||||
str[(index-1)-position] = tmp; | ||||
} | ||||
} | ||||
r116 | ||||
//***************************************************************** | ||||
//ABS_monitoreo es la funci�n principal del proyecto ABS_Monitoreo. | ||||
//Esta funci�n es la que se debe agregar en otros c�digos. | ||||
//***************************************************************** | ||||
r130 | char* ABS_monitoreo(int sel_atenuador, int sel_calibracion, float umbral, int pulsewidth){ | |||
r116 | ||||
//local variables | ||||
r130 | /* AT91S_PIO *pioc; | |||
r116 | pioc = pio_map(PIOC_BASE); | |||
unsigned int mask_sel_canal =PC4; //Aqu� se indican los pines que se desean usar como salidas. Las constantes PCx est�n defiidas en el header at91gpio.h | ||||
unsigned int mask_sel_atenuacion =PC5; | ||||
r130 | unsigned int mask_sel_calibracion =PC6;*/ | |||
unsigned long acumulado_ceros=0; | ||||
unsigned long acumulado_unos=0; | ||||
/* AT91S_ADC *padc; | ||||
AT91S_ADC *padd;*/ | ||||
r116 | FILE *fp; | |||
long int results1[NSAMPLES], results2[NSAMPLES], results3[NSAMPLES], results4[NSAMPLES]; | ||||
unsigned int i=0; | ||||
char fname[FNAMELEN]; | ||||
int j=0; | ||||
time_t now; | ||||
FILE *archivo; | ||||
float phase1; | ||||
float phase2; | ||||
r130 | char page0[30]; | |||
char page1[20]; | ||||
r145 | ||||
int cnt = 0; | ||||
r116 | //system("./map_clock"); | |||
r130 | /* | |||
r116 | if (configCLK() == 1) | |||
printf("clock ADC enable.\n"); | ||||
r130 | */ | |||
/* | ||||
r116 | //configurar tres pines como salida usando als m�scaras mask_sel_canal, mask_sel_atenuacion y mask_sel_calibracion. En este caso corresponden a los pines pc4, pc5 y pc6. | |||
pio_enable(pioc, mask_sel_canal); | ||||
pio_enable(pioc, mask_sel_atenuacion); | ||||
pio_enable(pioc, mask_sel_calibracion); | ||||
pio_output_enable(pioc, mask_sel_canal); //configurar pc4 como salida | ||||
pio_output_enable(pioc, mask_sel_atenuacion); //configurar pc5 como salida | ||||
pio_output_enable(pioc, mask_sel_calibracion); //configurar pc6 como salida | ||||
r130 | */ | |||
r116 | ||||
//Se modifican las salidas correspondientes a la selecci�n del atenuador y calibraci�n, de acuerdo a los par�metros ingresados en la funci�n ABS_monitoreo. | ||||
r130 | /*if ( sel_atenuador == 1) | |||
r117 | pio_out(pioc, mask_sel_atenuacion, sel_atenuador,1); | |||
else | ||||
pio_out(pioc, mask_sel_atenuacion, sel_atenuador,0); | ||||
if ( sel_calibracion == 1) | ||||
pio_out(pioc, mask_sel_calibracion, sel_calibracion,1); | ||||
else | ||||
r130 | pio_out(pioc, mask_sel_calibracion, sel_calibracion,0);*/ | |||
r116 | ||||
r130 | if ( sel_atenuador == 1) | |||
acumulado_unos = acumulado_unos + (1 << 5); | ||||
else | ||||
acumulado_ceros = acumulado_ceros + (1 << 5); | ||||
if ( sel_calibracion == 1) | ||||
acumulado_unos = acumulado_unos + (1 << 6); | ||||
else | ||||
acumulado_ceros = acumulado_ceros + (1 << 6); | ||||
r116 | ||||
r130 | strcpy (fname, "/mnt/sd/absmonitoreo.txt"); //Direcci�n y nombre del archivo donde se desea guardar los datos. | |||
r116 | if (fExists(fname)==0){ //si el archivo no existe, crea uno y le asigna el titulo | |||
archivo = fopen(fname,"a+"); | ||||
fprintf(archivo,"%s"," Registro de datos del ABS Control \n"); | ||||
fprintf(archivo,"%s"," Fecha y hora Fase UP Fase DOWN\n"); | ||||
fclose(archivo); | ||||
} | ||||
r130 | /* | |||
r116 | //configure ADC Settings | |||
padc=configADC1(); | ||||
padd=configADC2(); | ||||
r130 | */ | |||
//while (1){ | ||||
r116 | ||||
r130 | ENABLE_CHANNEL(padc, ADC_CH0+ADC_CH1); | |||
printf("\nAdquiriendo datos...\n"); //Indica en el terminal que se est�n adquiriendo datos (muestreando la se�al). | ||||
r116 | ||||
r130 | now = time(0); //Get current Time for File Name | |||
r116 | ||||
r130 | //Se pone la salida de selecci�n de canal para seleccionar el canal 1 del detector de fase | |||
acumulado_ceros = acumulado_ceros + (1 << 4); | ||||
pio_out(pioc, maskc_out_cntl, acumulado_ceros, 0); | ||||
pio_out(pioc, maskc_out_cntl, acumulado_unos, 1); | ||||
sleep(1); | ||||
r116 | ||||
r130 | //Se toman muestras para el canal 1 del detector de fase | |||
r145 | /*while(1){ | |||
r116 | for(i=0; i < NSAMPLES; i++){ | |||
ADC_INIT(padc); | ||||
results1[i] = GET_ADC0(padc); | ||||
results2[i] = GET_ADC1(padd); | ||||
} | ||||
r145 | ||||
r116 | if (checkTx(results1, results2, umbral, pulsewidth)==1){ //Se verifica que las muestras tomadas del canal 1 del datector de fase //correspondan a un pulso. | |||
break; | ||||
} | ||||
r145 | }*/ | |||
r116 | ||||
r145 | do{ | |||
for(i=0; i < NSAMPLES; i++){ | ||||
ADC_INIT(padc); | ||||
results1[i] = GET_ADC0(padc); | ||||
results2[i] = GET_ADC1(padd); | ||||
} | ||||
if (checkTx(results1, results2, umbral, pulsewidth)==1){ //Se verifica que las muestras tomadas del canal 1 del datector de fase //correspondan a un pulso. | ||||
break; | ||||
} | ||||
cnt += 1; | ||||
}while (cnt < NLOOPS); | ||||
r130 | //Se pone la salida de selecci�n de canal para seleccionar el canal 2 del detector de fase | |||
acumulado_ceros = acumulado_ceros - (1 << 4); | ||||
acumulado_unos = acumulado_unos + (1 << 4); | ||||
pio_out(pioc, maskc_out_cntl, acumulado_ceros, 0); | ||||
pio_out(pioc, maskc_out_cntl, acumulado_unos, 1); | ||||
sleep(1); | ||||
r116 | ||||
r130 | //Setoman muestras para el canal 2 del detector de fase | |||
r145 | /* while(1){ | |||
r116 | for(i=0; i < NSAMPLES; i++){ | |||
ADC_INIT(padc); | ||||
results3[i] = GET_ADC0(padc); | ||||
results4[i] = GET_ADC1(padd); | ||||
} | ||||
r145 | ||||
r116 | if (checkTx(results3, results4, umbral, pulsewidth)==1){ //Se verifica que las muestras tomadas del canal 2 del detector de fase //correspondan a un pulso. | |||
break; | ||||
} | ||||
r145 | }*/ | |||
cnt = 0; | ||||
do{ | ||||
for(i=0; i < NSAMPLES; i++){ | ||||
r116 | ||||
r145 | ADC_INIT(padc); | |||
results3[i] = GET_ADC0(padc); | ||||
results4[i] = GET_ADC1(padd); | ||||
} | ||||
r116 | ||||
r145 | if (checkTx(results3, results4, umbral, pulsewidth)==1){ //Se verifica que las muestras tomadas del canal 2 del detector de fase //correspondan a un pulso. | |||
break; | ||||
} | ||||
cnt += 1; | ||||
}while(cnt < NLOOPS); | ||||
r130 | //Una vez que se ha encontrado un pulso en cada canal, se calcula la fase de ambos. | |||
r116 | ||||
r130 | phase1 = getPhase(results1, results2); //Calcular la fase del canal 1 del detector de fase. | |||
phase2 = getPhase(results3, results4); //Calcular la fase del canal 2 del detector de fase. | ||||
//create Output File | ||||
r116 | ||||
r130 | strcpy (fname, "/mnt/sd/absmonitoreo.txt"); | |||
printf("\nTerminada la prueba # %d \n", j++); | ||||
fp=create_Output(fname, now); //Coloca la fecha y la hora en el archivo de texto | ||||
printf("mediana ch1 = %1.2f\n", phase1); //muestra resultado en terminal | ||||
printf("mediana ch2 = %1.2f\n", phase2); //muestra resultado en terminal | ||||
writeOutput(phase1, fp); //graba el resultado en el archivo de texto | ||||
writeOutput(phase2, fp); //graba el resultado en el archivo de texto | ||||
fprintf(fp, "\n"); //Pasa a la siguiente l�nea del archivo de texto | ||||
fclose(fp); | ||||
printf("Resultado guardado en %s \n", fname); | ||||
r116 | ||||
r130 | sleep(1); | |||
r116 | ||||
r130 | strcpy(page0,parameters.ID); | |||
strcat(page0,"\n-------\n"); | ||||
sprintf(page1,"UP:%1.2f DW:%1.2f\n",phase1, phase2); | ||||
strcat(page0,page1); | ||||
char *all_pages = malloc(strlen(page0)+1); | ||||
strcpy(all_pages, page0); | ||||
return all_pages; | ||||
// } | ||||
// return 0; | ||||
r116 | } | |||
/*============================================================================= | ||||
Function definitions | ||||
=============================================================================*/ | ||||
// Configures ADC registers in order to get a sample every 10us | ||||
AT91S_ADC * configADC1(void){ | ||||
//Variables a usar: | ||||
r130 | /* | |||
r116 | unsigned int maskc_adc =PC0; //Usamos ADC0 y ADC1 | |||
//configuro pin: | ||||
AT91S_PIO *pioc; | ||||
pioc = pio_map(PIOC_BASE); | ||||
pin_adc_enable(pioc,maskc_adc); //Habilitamos PC0 para usar con ADC0 y 1 | ||||
pio_disable_irq(pioc, maskc_adc); | ||||
pio_disable_multiple_driver(pioc, maskc_adc); | ||||
pio_disable_pull_ups(pioc, maskc_adc); | ||||
pio_input_enable(pioc, maskc_adc); | ||||
r130 | */ | |||
r116 | ||||
//Configuro el ADC: | ||||
r130 | //AT91S_ADC *padc; | |||
r116 | ||||
padc = adc_map1(ADC_BASE); | ||||
//clock ADC = 1MHz | ||||
//time startup = 8us | ||||
//time sample and hold = 2us | ||||
// hold | ||||
// ___________ | ||||
// start ___________| |___________ | ||||
// | ||||
// | --1.2us-- | --0.15us-- | | ||||
//ADC_RESET(padc); | ||||
CONFIG_ADC(padc,ADC_TRGEN_DIS | ADC_RES_10BIT | ADC_SLEEP_NORMAL_MODE | ADC_PRESCAL | ADC_STARTUP | ADC_SHTIM); | ||||
ENABLE_CHANNEL(padc,ADC_CH0); //habilito canal 0 | ||||
return padc; | ||||
} | ||||
AT91S_ADC * configADC2(void){ | ||||
//Variables a usar: | ||||
r130 | /* | |||
r116 | unsigned int maskc_adc =PC1; //Usamos ADC0 y ADC1 | |||
//configuro pin: | ||||
AT91S_PIO *piod; | ||||
piod = pio_map(PIOC_BASE); | ||||
r130 | pin_adc_enable(piod,maskc_adc); //Habilitamos PC1 para usar con ADC0 y 1 | |||
r116 | pio_disable_irq(piod, maskc_adc); | |||
pio_disable_multiple_driver(piod, maskc_adc); | ||||
pio_disable_pull_ups(piod, maskc_adc); | ||||
pio_input_enable(piod, maskc_adc); | ||||
r130 | */ | |||
r116 | //Configuro el ADC: | |||
r130 | //AT91S_ADC *padd; | |||
r116 | ||||
padd = adc_map1(ADC_BASE); | ||||
//clock ADC = 1MHz | ||||
//time startup = 8us | ||||
//time sample and hold = 2us | ||||
// hold | ||||
// ___________ | ||||
// start ___________| |___________ | ||||
// | ||||
// | --1.2us-- | --0.15us-- | | ||||
//ADC_RESET(padc); | ||||
CONFIG_ADC(padd,ADC_TRGEN_DIS | ADC_RES_10BIT | ADC_SLEEP_NORMAL_MODE | ADC_PRESCAL | ADC_STARTUP | ADC_SHTIM); | ||||
ENABLE_CHANNEL(padd,ADC_CH1); //habilito canal 1 | ||||
return padd; | ||||
} | ||||
//++++++++++++++++++++ | ||||
//creats the output file with a timestamp in the name | ||||
FILE * create_Output(char *fname, time_t rawtime){ | ||||
FILE *file; | ||||
char timestamp[80];//, counter[5]="dcv"; | ||||
//char str[4]; | ||||
struct tm * timeinfo; | ||||
//format time | ||||
timeinfo = localtime ( &rawtime ); | ||||
strftime (timestamp,sizeof(timestamp),"%a %y-%m-%d %H:%M:%S %Z",timeinfo); | ||||
//Creates the file name out of the #define parameters | ||||
r130 | strcpy (fname, "/mnt/sd/absmonitoreo.txt"); | |||
r116 | file = fopen(fname,"a+"); | |||
fprintf(file,"%s", timestamp); | ||||
//printf("\nTerminada la prueba # %d. Guardando resultado en %s\n",r, fname); | ||||
//printf("\nTerminada la prueba # %d/%d. Writing data to the file %s\n",r+1 , REP, fname); | ||||
//printf("\nAAAAAAAAAA %d...%s\n", counter[1], fname); | ||||
// return file pointer | ||||
return file; | ||||
} | ||||
//++++++++++++++++++++ | ||||
//tests if a file already exists. returns 1 if it exists and 0 if it doesn't | ||||
//Funci�n checkTx verifica que la se�al muestreada corresponda a un pulso. | ||||
//results1 y results2 son los arreglos que contienen los datos muestreados por ambos canales del ADC del embebido. | ||||
//umbral indica qu� valor debe superar una muestra para considerarla un posible pulso o pico. | ||||
//pulsewidth indica cu�ntas muestras consecutivas deben superar el umbral para que se considere que se ha detectado un pulso. | ||||
int checkTx(long int results1[],long int results2[], float umbral, int pulsewidth){ | ||||
int i, cont; | ||||
float z[NSAMPLES], sum, avg; | ||||
int isSignal, pulse; | ||||
for(i=0;i<NSAMPLES;i++){ | ||||
z[i] =sqrt(1.0*results1[i]*results1[i]+1.0*results2[i]*results2[i]); | ||||
} | ||||
pulse = 0; | ||||
isSignal = 0; | ||||
cont =0; | ||||
sum = 0; | ||||
for(i=0;i<NSAMPLES;i++){ | ||||
sum += z[i]; | ||||
avg = sum/(i+1); | ||||
if ((z[i] - avg) > umbral){ | ||||
if (isSignal == 1){ | ||||
cont += 1; | ||||
} | ||||
if (cont == pulsewidth){ | ||||
pulse = 1; | ||||
break; | ||||
} | ||||
isSignal = 1; | ||||
continue; | ||||
isSignal = 0; | ||||
cont = 0; | ||||
} | ||||
} | ||||
return pulse; //devuelve un entero: 1 si se ha detectado pulso, de lo contrario, 0. | ||||
} | ||||
int fExists(char * fname){ | ||||
FILE * file; | ||||
file = fopen (fname, "r"); | ||||
if (file == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
fclose(file); | ||||
return 1; | ||||
} | ||||
//Funci�n que calcula la mediana de un conjunto de muestras | ||||
double mediana(long int *results,unsigned int cuenta){ | ||||
unsigned int i=0,j=0,aux=0; | ||||
double median=0; | ||||
/*Calculo mediana */ | ||||
for(i=0;i<cuenta-1;i++){ | ||||
for (j=i+1;j<cuenta;j++){ | ||||
if(results[i]>results[j] ){ | ||||
aux=results[i]; | ||||
results[i]=results[j]; | ||||
results[j]=aux; | ||||
} | ||||
} | ||||
} | ||||
median=results[cuenta/2]; | ||||
return median; | ||||
} | ||||
//Funci�n que halla la fase de la se�al. | ||||
//Tiene como entradas las muestras correspondientes a la parte real e imaginaria de la se�al. | ||||
float getPhase(long int results1[],long int results2[]){ | ||||
unsigned int count=0, i=0,umbral=1000; | ||||
//long int results1[]; | ||||
//long int results2[]; | ||||
long int power[NSAMPLES]; | ||||
long int sumI=0,sumQ=0,I[NSAMPLES], Q[NSAMPLES],II[NSAMPLES], QQ[NSAMPLES]; | ||||
double median1=0,median2=0; | ||||
long int promedioI=0,promedioQ=0;/*Calculo mediana 1*/ | ||||
float resultado=0; | ||||
for(i=0;i<NSAMPLES;i++){ | ||||
I[i] =results1[i]; | ||||
Q[i] =results2[i]; | ||||
} | ||||
/*Calculo mediana 1*/ | ||||
median1=mediana(I,NSAMPLES); | ||||
/*Calculo mediana 2*/ | ||||
median2=mediana(Q,NSAMPLES); | ||||
for(i=0;i<NSAMPLES;i++){ | ||||
I[i] =results1[i]; | ||||
Q[i] =results2[i]; | ||||
} | ||||
for(i = 0; i < NSAMPLES ; i++){ | ||||
I[i]=(I[i]-median1); | ||||
Q[i]=(Q[i]-median2); | ||||
} | ||||
for(i = 0; i < NSAMPLES ; i++){ | ||||
power[i]=I[i]*I[i]+Q[i]*Q[i]; | ||||
if(power[i] > umbral) | ||||
{ | ||||
II[count]=I[i]; | ||||
QQ[count]=Q[i]; | ||||
count=count+1; | ||||
} | ||||
} | ||||
for(i = 0; i < count ; i++){ | ||||
sumI=sumI+II[i]; | ||||
sumQ=sumQ+QQ[i]; | ||||
} | ||||
promedioI=sumI; | ||||
promedioQ=sumQ; | ||||
resultado = atan2(1.0*promedioI,1.0*promedioQ)*180/3.1416+62-44; | ||||
return resultado; | ||||
} | ||||
//Funci�n que muestra la fase detectada en el terminal y tambi�n la graba en el archivo de texto. | ||||
void writeOutput(float resultado, FILE * output){ | ||||
// | ||||
fprintf(output," %1.2f ",resultado); //graba resultado en archivo .txt | ||||
// | ||||
} | ||||
int configCLK(){ | ||||
//configuro pin: | ||||
AT91S_PMC *sys_clock; | ||||
sys_clock = clock_map(CLOCK_BASE); | ||||
enable_clock_adc(sys_clock); | ||||
//printf("clock ADC enable.\n"); | ||||
return 1; | ||||
} | ||||