/* * 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 * * Modified by Iván Manay since Nov 2012 * -From UDP to TCP. * -Use of a frame for TCP communications with the central control module. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "./Librerias/at91gpio.h" //#include "./Librerias/Mensajes.h" #include "./Librerias/at91adc.h" //clock #include "./Librerias/at91sysclock.h" #define PUERTO_SERVIDOR 5500 #define TAM_BUFFER 1024 #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 #define mask_sel_canal PC4 //MONITORING CONTROL #define mask_sel_atenuacion PC5 #define mask_sel_calibracion PC6 #define maskb_in PB16+PB18+PB20+PB30+PB24+PB22 //MSB-UP-LSB MSB-DOWN-LSB //VERIFICACION #define maskc_in_adc PC0+PC1 #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 */ //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 #define NSAMPLES 10 //defines how many samples are taken in one data acqu- // isation loop #define NLOOPS 200 // Number of loops for the transmisor checking #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) char *buff_experimento= NULL; AT91S_PIO *pioc; AT91S_PIO *piob; AT91S_PIO *pio_adc; AT91S_ADC *padc; AT91S_ADC *padd; struct control_module_parameters { char ID[20]; char param2[20]; char param3[20]; char param4[20]; }; typedef struct control_module_parameters cmp; char *header = NULL; char *TypeOfInstrument = NULL; char *iDSource = NULL; char *iDDestino = NULL; char *rx_len = NULL; char *cmd = NULL; char *rx_data = NULL; char *crc = NULL; cmp parameters; /* * Zona de declaracion de cabeceras. */ cmp inicializa_modulo(cmp p, char *filename); int inicializa_ethernet(); int rxData(int, char*); void txData(int, char*); void inicializa_gpio(); void inicializa_adc(); void procesa_peticion(char *rx_buffer, char *tx_buffer); int cambia_apuntamiento(char *puntero_char); int carga_experimento(char *nombre_archivo); char *chequeo_sistema(char *filename, char *numero_muestras); void escribe_experimento(char *data, char filename[]); char *Lee_experimento(char *filename); void consigue_nombre_experimento(char *rx_data, char filename[]); void SplitFrame(char *frame); void intToStr( int number, char* str ); int update_app(char *filename, char *ip_number); //ABS monitoring //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); 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(); // /* * */ int main(int argc, char *argv[]){ // arg[1] : Archivo de configuracion del modulo de control int servSocket; int clntSocket; char *rx_buffer = (char *) malloc(TAM_BUFFER); char *tx_buffer = (char *) malloc(TAM_BUFFER); /* Inicializa parametros del modulo*/ parameters = inicializa_modulo(parameters, argv[1]); printf("%s\n%s\n%s\n%s\n",parameters.ID, parameters.param2, parameters.param3, parameters.param4); /* Inicializa red*/ servSocket = inicializa_ethernet(); /* Inicializamos el puerto GPIO del sistema embebido GSBC-9260S */ inicializa_gpio(); inicializa_adc(); 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(){ struct sockaddr_in inf_servidor; int servSocket; int resultado; /* Haciendo la estructura local*/ 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 */ servSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); if (servSocket == -1){ printf("No se establecio correctamente el socket: socket()\n"); //ERROR_FATAL("No se establecio correctamente el socket: socket()\n"); exit(-1); } /* Se asocia el socket a un puerto y una IP */ resultado = bind(servSocket,(struct sockaddr *)&inf_servidor,sizeof(inf_servidor)); if (resultado== -1){ printf("No se establecio correctamente el socket: bind()\n"); //ERROR_FATAL("No se establecio correctamente el socket: bind()\n"); exit(-1); } if (listen(servSocket, MAXPENDING) < 0){ printf("listen() failed\n"); exit(-1); } return servSocket; } int rxData(int servSocket, char* rx_buffer){ int clntSocket; struct sockaddr_in inf_cliente; int numbytes_recibidos; unsigned int inf_client_Len; printf("\nEsperando solicitud de cliente...\n"); /* 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"); 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; } void txData(int clntSocket, char* data){ /* Echo message back to client */ if (send(clntSocket, data, strlen(data), 0) != strlen(data)) printf("send() failed\n"); close(clntSocket); /* Close client socket */ } /* * Esta funcion incializa el puerto GPIO */ void inicializa_gpio(){ 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 pioc = pio_map(PIOC_BASE); 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); // 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); //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); } void inicializa_adc(){ if (configCLK() == 1) printf("clock ADC enable.\n"); //configure ADC Settings padc=configADC1(); padd=configADC2(); } /* * Divide rx frame into the frame components */ 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'; 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'; cmd = malloc(5); *cmd = *(frame + 26); *(cmd + 1) = *(frame + 27); *(cmd + 2) = *(frame + 28); *(cmd + 3) = *(frame + 29); *(cmd + 4) = '\0'; int l = atoi(rx_len); rx_data = malloc(l + 1); 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'; } /* * Esta funcion procesa el mensaje de peticion y genera respuesta */ void procesa_peticion(char *rx_buffer, char *tx_buffer){ // int n = 0; char filename1[50]; char filename2[] = "verificacion.txt"; char *tx_data = NULL; char *tx_len = NULL; SplitFrame(rx_buffer); if ((cmd == NULL) || (rx_data == NULL)){ printf("procesarPeticion: formato de mensaje incorrecto"); //ERROR("procesarPeticion: formato de mensaje incorrecto"); } else{ if(strcmp(cmd,"SNDF") == 0){ escribe_experimento(rx_data,filename1); carga_experimento(filename1); cambia_apuntamiento("0"); tx_data = (char*)malloc(3); tx_data = "OK"; } else if(strcmp(cmd,"GETF") == 0){ consigue_nombre_experimento(rx_data,filename1); //get a filename from frame tx_data = Lee_experimento(filename1); //return a pointer to the content of the filename } 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); printf("%s\n",tx_data); } else if(strcmp(cmd,"BGPH") == 0){ tx_data = ABS_monitoreo(1, 0, 50, 10); // tx_data = "Not implemented\n"; printf("%s\n",tx_data); } else if(strcmp(cmd,"LWPH") == 0){ tx_data = ABS_monitoreo(0, 0, 50, 10); // tx_data = "Not implemented\n"; printf("%s\n",tx_data); } else if(strcmp(cmd,"NTST") == 0){ tx_data = malloc(strlen(parameters.ID) + 1); strcpy(tx_data,parameters.ID); printf("%s\n",tx_data); } else if(strcmp(cmd,"UAPP") == 0){ tx_data = malloc(strlen(parameters.ID) + 1); strcpy(tx_data,parameters.ID); printf("%s\n",tx_data); } else{ tx_data = (char*)malloc(6); tx_data = "Error"; printf("procesa_peticion: comando no reconocido"); //ERROR("procesa_peticion: comando no reconocido"); } tx_len = malloc(7); int number = strlen(tx_data); intToStr(number, tx_len ); strcpy(tx_buffer,header); //3 strcat(tx_buffer,TypeOfInstrument); //3 strcat(tx_buffer,parameters.ID); //7 strcat(tx_buffer,iDSource); //7 strcat(tx_buffer,tx_len); //6 strcat(tx_buffer,cmd); //4 strcat(tx_buffer,tx_data); //? strcat(tx_buffer,crc); //1 } } char* Lee_experimento(char filename[]){ char *buffer = NULL; FILE * fd = fopen(filename,"r"); fseek(fd, 0, SEEK_END); size_t sz = ftell(fd); fseek(fd, 0, SEEK_SET); buffer = malloc(sz); fread(buffer,sizeof(char),sz,fd); fclose(fd); char *ans = malloc(sz + 1); strcpy(ans, buffer); ans[sz] = '\0'; return ans; } /* * Esta función genera el archivo de experimento a partir de la trama TCP recibida */ void escribe_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); } void consigue_nombre_experimento(char *p_data, char filename[]){ int i = 0; while (*p_data != '\n'){ filename[i] = *p_data; i++; p_data++; } filename[i] = '\0'; } /* * 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; Archivo_Fd = fopen(nombre_archivo,"r"); // Se procede a abrir el archivo, segun la ruta especificada if(!Archivo_Fd){ printf("carga_archivo: No se pudo abrir el archivo!!! --> fopen()\n"); //ERROR("carga_archivo: No se pudo abrir el archivo!!! --> fopen()\n"); 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); char *puntero= strstr(buffer_temporal,".ab1"); // Se procede a eliminar la cabecera del archivo 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 printf("%s\n",puntero_char); // contiene cada dato, para este caso es 7 // 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" 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]); } } pio_out(pioc, maskc_out_beam, acumulado_unos, 1); pio_out(pioc, maskc_out_beam, acumulado_ceros, 0); return 1; } /* * 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]; /*strcpy(page0,"Verificacion\n"); strcat(page0,parameters.ID);*/ strcpy(page0,parameters.ID); strcat(page0,"\n-------\n"); 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; } int update_app(char *filename, char *ip_number){ char cmd[80]; strcpy(cmd,"tftp -gr"); strcat(cmd," "); strcat(cmd,filename); strcat(cmd," "); strcat(cmd,ip_number); system(cmd); printf(cmd); return 0; } /* * */ cmp inicializa_modulo(cmp p, char *filename){ //FILE *fd = fopen("configuration.txt","r"); FILE *fd = fopen(filename,"r"); fgets(p.ID,20,fd); p.ID[7]='\0'; fgets(p.param2,20,fd); p.param2[10]='\0'; fgets(p.param3,20,fd); p.param3[10]='\0'; fgets(p.param4,20,fd); p.param4[10]='\0'; fclose(fd); return p; } /* * */ 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; } } //***************************************************************** //ABS_monitoreo es la funci�n principal del proyecto ABS_Monitoreo. //Esta funci�n es la que se debe agregar en otros c�digos. //***************************************************************** char* ABS_monitoreo(int sel_atenuador, int sel_calibracion, float umbral, int pulsewidth){ //local variables /* AT91S_PIO *pioc; 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; unsigned int mask_sel_calibracion =PC6;*/ unsigned long acumulado_ceros=0; unsigned long acumulado_unos=0; /* AT91S_ADC *padc; AT91S_ADC *padd;*/ 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; char page0[30]; char page1[20]; int cnt = 0; //system("./map_clock"); /* if (configCLK() == 1) printf("clock ADC enable.\n"); */ /* //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 */ //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. /*if ( sel_atenuador == 1) 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 pio_out(pioc, mask_sel_calibracion, sel_calibracion,0);*/ 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); strcpy (fname, "/mnt/sd/absmonitoreo.txt"); //Direcci�n y nombre del archivo donde se desea guardar los datos. 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); } /* //configure ADC Settings padc=configADC1(); padd=configADC2(); */ //while (1){ 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). now = time(0); //Get current Time for File Name //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); //Se toman muestras para el canal 1 del detector de fase /*while(1){ 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; } }*/ 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); //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); //Setoman muestras para el canal 2 del detector de fase /* while(1){ for(i=0; i < NSAMPLES; i++){ ADC_INIT(padc); results3[i] = GET_ADC0(padc); results4[i] = GET_ADC1(padd); } 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 = 0; do{ for(i=0; i < NSAMPLES; i++){ ADC_INIT(padc); results3[i] = GET_ADC0(padc); results4[i] = GET_ADC1(padd); } 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); //Una vez que se ha encontrado un pulso en cada canal, se calcula la fase de ambos. 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 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); sleep(1); strcpy(page0,parameters.ID); strcat(page0,"\n-------\n"); //sprintf(page1,"UP:%1.2f DW:%1.2f\n",phase1, phase2); sprintf(page1,"%1.2f %1.2f\n",phase1, phase2); strcat(page0,page1); char *all_pages = malloc(strlen(page0)+1); strcpy(all_pages, page0); return all_pages; // } // return 0; } /*============================================================================= Function definitions =============================================================================*/ // Configures ADC registers in order to get a sample every 10us AT91S_ADC * configADC1(void){ //Variables a usar: /* 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); */ //Configuro el ADC: //AT91S_ADC *padc; 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: /* unsigned int maskc_adc =PC1; //Usamos ADC0 y ADC1 //configuro pin: AT91S_PIO *piod; piod = pio_map(PIOC_BASE); pin_adc_enable(piod,maskc_adc); //Habilitamos PC1 para usar con ADC0 y 1 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); */ //Configuro el ADC: //AT91S_ADC *padd; 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 strcpy (fname, "/mnt/sd/absmonitoreo.txt"); 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 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;iresults[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 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; }