##// END OF EJS Templates
imanay -
r121:122
parent child
Show More
@@ -1,1030 +1,1035
1 1 /*
2 2 * Servidor.c
3 3 *
4 4 * Created on: Nov 3, 2009
5 5 * Author: Jose Francisco Quenta
6 6 *
7 7 * Se implementa:
8 8 * -Carga en memoria los apuntes contenidos en un archivo de experimentos: apunte0 -> GPIO
9 9 * -Cambio de apunte.
10 10 * -Lectura del estado actual del apunte y grabado del mismo en un archivo
11 11 *
12 12 * Modified by Iván Manay since Nov 2012
13 13 * -From UDP to TCP.
14 14 * -Use of a frame for TCP communications with the central control module.
15 15 */
16 16
17 17 #include <stdio.h>
18 18 #include <stdlib.h>
19 19 #include <string.h>
20 20 #include <unistd.h>
21 21 #include <errno.h>
22 22
23 23 #include <sys/types.h>
24 24 #include <sys/socket.h>
25 25 #include <netinet/in.h>
26 26 #include <arpa/inet.h>
27 27 #include <netdb.h>
28 28 #include <time.h>
29 29 #include <math.h>
30 30
31 31 #include "./Librerias/at91gpio.h"
32 32 //#include "./Librerias/Mensajes.h"
33 33 #include "./Librerias/at91adc.h"
34 34 //clock
35 35 #include "./Librerias/at91sysclock.h"
36 36
37 37 #define PUERTO_SERVIDOR 5500
38 38 #define TAM_BUFFER 1024
39 39
40 40 #define maskc_out PC30+PC28+PC26+PC24+PC22+PC20 //MSB-UP-LSB MSB-DOWN-LSB //APUNTE
41 41
42 42 #define maskb_in PB16+PB18+PB20+PB30+PB24+PB22 //MSB-UP-LSB MSB-DOWN-LSB //VERIFICACION
43 43
44 44 #define bit_up_2 0x00010000 //Mascara de cada bit a revisar: bit_up_2 es MSB
45 45 #define bit_up_1 0x00040000
46 46 #define bit_up_0 0x00100000
47 47 #define bit_dow_2 0x40000000
48 48 #define bit_dow_1 0x01000000
49 49 #define bit_dow_0 0x00400000
50 50
51 51 #define MyID 11
52 52 #define MAXPENDING 5 /* Maximum outstanding connection requests */
53 53
54 54 //parameters for the name of the output file
55 55 #define FPRE "AD" //prefix for the output file name
56 56 #define FEXT ".out" //file extension for the output file
57 57 #define FNAMELEN 40
58 58
59 59 //ADC parameters
60 60 #define REP 1 //defines how many times the data acquisation loop is repeated
61 61 #define NSAMPLES 100 //defines how many samples are taken in one data acqu-
62 62 // isation loop
63 63 #define CNVTIME 14.3 //defines how long it takes to get one sample. Value
64 64 // is only needed for the output file, doesn't change
65 65 // any ADC configurations
66 66 #define UREF 3.3 //Reference Voltage of ADC (max. ADC Voltage)
67 67 #define ADCRES 1023 //Resolution of ADC (10bit=1023)
68 68
69 69
70 70 char *buff_experimento= NULL;
71 71
72 72 AT91S_PIO *pioc;
73 73 AT91S_PIO *piob;
74 74
75 75 struct control_module_parameters {
76 76 char ID[20];
77 77 char param2[20];
78 78 char param3[20];
79 79 char param4[20];
80 80 };
81 81
82 82 typedef struct control_module_parameters cmp;
83 83
84 84 char *header = NULL;
85 85 char *TypeOfInstrument = NULL;
86 86 char *iDSource = NULL;
87 87 char *iDDestino = NULL;
88 88 char *rx_len = NULL;
89 89 char *cmd = NULL;
90 90 char *rx_data = NULL;
91 91 char *crc = NULL;
92 92
93 93 cmp parameters;
94 94 /*
95 95 * Zona de declaracion de cabeceras.
96 96 */
97 97 cmp inicializa_modulo(cmp p);
98 98 int inicializa_ethernet();
99 99 int rxData(int, char*);
100 100 void txData(int, char*);
101 101 void inicializa_gpio();
102 102 void procesa_peticion(char *rx_buffer, char *tx_buffer);
103 103 int cambia_apuntamiento(char *puntero_char);
104 104 int carga_experimento(char *nombre_archivo);
105 105 char *chequeo_sistema(char *filename, char *numero_muestras);
106 106 void recibe_experimento(char *data, char filename[]);
107 107 void SplitFrame(char *frame);
108 108 void intToStr( int number, char* str );
109 109
110 110 //ABS monitoring
111 111 int ABS_monitoreo(int sel_atenuador, int sel_calibracion, float umbral, int pulsewidth);
112 112
113 113 AT91S_ADC * configADC1(void);
114 114 AT91S_ADC * configADC2(void);
115 115
116 116 FILE * create_Output(char*, time_t);
117 117
118 118 void writeOutput(float resultado, FILE * output);
119 119
120 120 int checkTx(long int results1[],long int results2[], float umbral, int pulsewidth);
121 121
122 122 double mediana(long int *results, unsigned int cuenta);
123 123 float getPhase(long int results1[], long int results2[]);
124 124
125 125 int fExists(char *);
126 126 int configCLK();
127 127 //
128 128
129 129 /*
130 130 *
131 131 */
132 132 int main(){
133 133
134 134 int servSocket;
135 135 int clntSocket;
136 136
137 137
138 138 char *rx_buffer = (char *) malloc(TAM_BUFFER);
139 139 char *tx_buffer = (char *) malloc(TAM_BUFFER);
140 140 /* Inicializa parametros del modulo*/
141 141 parameters = inicializa_modulo(parameters);
142 142 printf("%s\n%s\n%s\n%s\n",parameters.ID, parameters.param2, parameters.param3, parameters.param4);
143 143 /* Inicializa red*/
144 144 servSocket = inicializa_ethernet();
145 145 /* Inicializamos el puerto GPIO del sistema embebido GSBC-9260S */
146 146 inicializa_gpio();
147 147
148 148 while(1){
149 149 // Recepción TCP de petición
150 150 clntSocket = rxData(servSocket, rx_buffer);
151 151 //testpoint
152 152 printf("rx:%s\n",rx_buffer);
153 153 // Procesamiento de la petición
154 154 procesa_peticion(rx_buffer, tx_buffer);
155 155 //testpoint
156 156 printf("tx:%s\n",tx_buffer);
157 157 // Respuesta del modulo de control
158 158 txData(clntSocket, tx_buffer);
159 159
160 160 }
161 161 }
162 162
163 163
164 164 int inicializa_ethernet(){
165 165
166 166 struct sockaddr_in inf_servidor;
167 167
168 168 int servSocket;
169 169
170 170 int resultado;
171 171
172 172 /* Haciendo la estructura local*/
173 173 memset(&inf_servidor, 0, sizeof(inf_servidor));
174 174 inf_servidor.sin_family= AF_INET;
175 175 inf_servidor.sin_port= htons(PUERTO_SERVIDOR);
176 176 inf_servidor.sin_addr.s_addr= INADDR_ANY;
177 177
178 178 /* Se establece el socket */
179 179 servSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
180 180 if (servSocket == -1){
181 181 printf("No se establecio correctamente el socket: socket()\n");
182 182 //ERROR_FATAL("No se establecio correctamente el socket: socket()\n");
183 183 exit(-1);
184 184 }
185 185
186 186 /* Se asocia el socket a un puerto y una IP */
187 187 resultado = bind(servSocket,(struct sockaddr *)&inf_servidor,sizeof(inf_servidor));
188 188 if (resultado== -1){
189 189 printf("No se establecio correctamente el socket: bind()\n");
190 190 //ERROR_FATAL("No se establecio correctamente el socket: bind()\n");
191 191 exit(-1);
192 192 }
193 193
194 194 if (listen(servSocket, MAXPENDING) < 0){
195 195 printf("listen() failed\n");
196 196 exit(-1);
197 197 }
198 198
199 199 return servSocket;
200 200
201 201 }
202 202
203 203 int rxData(int servSocket, char* rx_buffer){
204 204
205 205 int clntSocket;
206 206 struct sockaddr_in inf_cliente;
207 207 int numbytes_recibidos;
208 208 unsigned int inf_client_Len;
209 209
210 210 printf("\nEsperando solicitud de cliente...\n");
211 211
212 212 /* Set the size of the in-out parameter */
213 213 inf_client_Len = sizeof(inf_cliente);
214 214 /* Se espera hasta que un cliente se conecte */
215 215 if ((clntSocket = accept(servSocket, (struct sockaddr *) &inf_cliente,
216 216 &inf_client_Len)) < 0)
217 217 printf("accept() failed\n");
218 218
219 219 if ((numbytes_recibidos = recv(clntSocket, rx_buffer, TAM_BUFFER, 0)) < 0)
220 220 printf("recv() failed\n");
221 221
222 222 /* Se procede a procesar los datos recibidos */
223 223 rx_buffer[numbytes_recibidos]= '\0';
224 224
225 225 return clntSocket;
226 226 }
227 227
228 228 void txData(int clntSocket, char* data){
229 229
230 230 /* Echo message back to client */
231 231 if (send(clntSocket, data, strlen(data), 0) != strlen(data))
232 232 printf("send() failed\n");
233 233
234 234 close(clntSocket); /* Close client socket */
235 235 }
236 236
237 237 /*
238 238 * Esta funcion incializa el puerto GPIO
239 239 */
240 240 void inicializa_gpio(){
241 241
242 242 // Configuracion de los pines de APUNTE
243 243 pioc = pio_map(PIOC_BASE);
244 244 pio_enable(pioc, maskc_out);
245 245 pio_disable_irq(pioc, maskc_out);
246 246 pio_disable_multiple_driver(pioc, maskc_out);
247 247 pio_disable_pull_ups(pioc, maskc_out);
248 248 pio_synchronous_data_output(pioc, maskc_out);
249 249 pio_output_enable(pioc, maskc_out);
250 250
251 251 // Configuracion de los pines de VERIFICACION
252 252 piob = pio_map(PIOB_BASE);
253 253 pio_enable(piob, maskb_in);
254 254 pio_disable_irq(piob, maskb_in);
255 255 pio_disable_multiple_driver(piob, maskb_in);
256 256 pio_disable_pull_ups(piob, maskb_in);
257 257 pio_input_enable(piob, maskb_in);
258 258 }
259 259
260 260
261 261 /*
262 262 * Divide rx frame into the frame components
263 263 */
264 264 void SplitFrame(char *frame){
265 265 header = malloc(4);
266 266 *header = *frame;
267 267 *(header + 1) = *(frame + 1);
268 268 *(header + 2) = *(frame + 2);
269 269 *(header + 3) = '\0';
270 270 TypeOfInstrument = malloc(4);
271 271 *TypeOfInstrument = *(frame + 3);
272 272 *(TypeOfInstrument + 1) = *(frame + 4);
273 273 *(TypeOfInstrument + 2) = *(frame + 5);
274 274 *(TypeOfInstrument + 3) = '\0';
275 275 iDSource = malloc(8);
276 276 *iDSource = *(frame + 6);
277 277 *(iDSource + 1) = *(frame + 7);
278 278 *(iDSource + 2) = *(frame + 8);
279 279 *(iDSource + 3) = *(frame + 9);
280 280 *(iDSource + 4) = *(frame + 10);
281 281 *(iDSource + 5) = *(frame + 11);
282 282 *(iDSource + 6) = *(frame + 12);
283 283 *(iDSource + 7) = '\0';
284 284 iDDestino = malloc(8);
285 285 *iDDestino = *(frame + 13);
286 286 *(iDDestino + 1) = *(frame + 14);
287 287 *(iDDestino + 2) = *(frame + 15);
288 288 *(iDDestino + 3) = *(frame + 16);
289 289 *(iDDestino + 4) = *(frame + 17);
290 290 *(iDDestino + 5) = *(frame + 18);
291 291 *(iDDestino + 6) = *(frame + 19);
292 292 *(iDDestino + 7) = '\0';
293 293 rx_len = malloc(7);
294 294 *rx_len = *(frame + 20);
295 295 *(rx_len + 1) = *(frame + 21);
296 296 *(rx_len + 2) = *(frame + 22);
297 297 *(rx_len + 3) = *(frame + 23);
298 298 *(rx_len + 4) = *(frame + 24);
299 299 *(rx_len + 5) = *(frame + 25);
300 300 *(rx_len + 6) = '\0';
301 301 cmd = malloc(5);
302 302 *cmd = *(frame + 26);
303 303 *(cmd + 1) = *(frame + 27);
304 304 *(cmd + 2) = *(frame + 28);
305 305 *(cmd + 3) = *(frame + 29);
306 306 *(cmd + 4) = '\0';
307 307
308 308 int l = atoi(rx_len);
309 309 rx_data = malloc(l + 1);
310 310 int i;
311 311 for (i = 30; i < 30 + l; i++)
312 312 *(rx_data + (i-30)) = *(frame + i);
313 313 *(rx_data + l) = '\0';
314 314 crc = malloc(2);
315 315 *crc = *(frame + 30 + l);
316 316 *(crc + 1) = '\0';
317 317 }
318 318
319 319
320 320 /*
321 321 * Esta funcion procesa el mensaje de peticion y genera respuesta
322 322 */
323 323 void procesa_peticion(char *rx_buffer, char *tx_buffer){
324 324 // int n = 0;
325 325 char filename1[50];
326 326 char filename2[] = "verificacion.txt";
327 327 char *tx_data = NULL;
328 328 char *tx_len = NULL;
329 329 SplitFrame(rx_buffer);
330 330
331 331 if ((cmd == NULL) || (rx_data == NULL)){
332 332 printf("procesarPeticion: formato de mensaje incorrecto");
333 333 //ERROR("procesarPeticion: formato de mensaje incorrecto");
334 334
335 335 }
336 336 else{
337 337 if(strcmp(cmd,"SNDF") == 0){
338 338 recibe_experimento(rx_data,filename1);
339 339 carga_experimento(filename1);
340 340 cambia_apuntamiento("0");
341 341 tx_data = (char*)malloc(3);
342 342 tx_data = "OK";
343 343 }
344 344 else if(strcmp(cmd,"CHGB") == 0){
345 345 cambia_apuntamiento(rx_data);
346 346 tx_data = (char*)malloc(3);
347 347 tx_data = "OK";
348 348 }
349 349 else if(strcmp(cmd,"ANST") == 0){
350 350 tx_data = chequeo_sistema(filename2,rx_data);
351 printf("%s\n",tx_data);
352 }
353 else if(strcmp(cmd,"ANPH") == 0){
351 354 ABS_monitoreo(1, 1, 50, 10);
355 tx_data = "Not implemented\n";
352 356 printf("%s\n",tx_data);
353 357 }
354 358 else if(strcmp(cmd,"NTST") == 0){
355 359 tx_data = malloc(strlen(parameters.ID) + 1);
356 360 strcpy(tx_data,parameters.ID);
357 361 printf("%s\n",tx_data);
358 362 }
359 363 else{
360 364 tx_data = (char*)malloc(6);
361 365 tx_data = "Error";
362 366 printf("procesa_peticion: comando no reconocido");
363 367 //ERROR("procesa_peticion: comando no reconocido");
364 368 }
365 369
366 370 tx_len = malloc(7);
367 371 int number = strlen(tx_data);
368 372 intToStr(number, tx_len );
369 373
370 374 strcpy(tx_buffer,header); //3
371 375 strcat(tx_buffer,TypeOfInstrument); //3
372 376 strcat(tx_buffer,parameters.ID); //7
373 377 strcat(tx_buffer,iDSource); //7
374 378 strcat(tx_buffer,tx_len); //6
375 379 strcat(tx_buffer,cmd); //4
376 380 strcat(tx_buffer,tx_data); //?
377 381 strcat(tx_buffer,crc); //1
378 382
379 383 }
380 384
381 385 }
382 386
383 387 /*
384 388 * Esta función genera el archivo de experimento a partir de la trama TCP recibida
385 389 */
386 390 void recibe_experimento(char *p_data, char filename[]){
387 391 FILE *fd;
388 392 int i = 0;
389 393
390 394 while (*p_data != '\n'){
391 395 filename[i] = *p_data;
392 396 i++;
393 397 p_data++;
394 398 }
395 399 filename[i] = '\0';
396 400 p_data = p_data - i;
397 401 fd = fopen(filename,"w");
398 402 fprintf(fd, p_data);
399 403 fclose(fd);
400 404 }
401 405
402 406 /*
403 407 * Esta funcion carga un archivo en un buffer que esta ubicado en memoria, luego
404 408 * este buffer es usado en la funcion "cambia_apuntamiento" para obtener el dato
405 409 * que sera usado en el cambio de apuntamiento.
406 410 */
407 411 int carga_experimento(char *nombre_archivo){
408 412
409 413 FILE *Archivo_Fd;
410 414
411 415 char *cadena = (char *) malloc(25);
412 416
413 417 int longitud_cadena;
414 418 int num_bytes= 0;
415 419 int num_filas= 0;
416 420
417 421 Archivo_Fd = fopen(nombre_archivo,"r"); // Se procede a abrir el archivo, segun la ruta especificada
418 422 if(!Archivo_Fd){
419 423 printf("carga_archivo: No se pudo abrir el archivo!!! --> fopen()\n");
420 424 //ERROR("carga_archivo: No se pudo abrir el archivo!!! --> fopen()\n");
421 425 return -1;
422 426 }else{
423 427
424 428 while(!feof(Archivo_Fd)){ // Se procede a calcular la longitud del archivo para separar memoria
425 429 fgets(cadena,20,Archivo_Fd);
426 430 longitud_cadena= strlen(cadena);
427 431 cadena[longitud_cadena-1] = '\0';
428 432 num_bytes = num_bytes + longitud_cadena;
429 433 num_filas++;
430 434 }
431 435
432 436 rewind(Archivo_Fd); // Se reinicia el puntero del archivo
433 437
434 438 char *buffer_temporal = (char *) malloc(num_bytes+1); // Se separa espacio de memoria segun
435 439 // la longitud del archivo
436 440 fread(buffer_temporal, sizeof(char), num_bytes, Archivo_Fd);
437 441
438 442 char *puntero= strstr(buffer_temporal,".ab1"); // Se procede a eliminar la cabecera del archivo
439 443 puntero= puntero + 12;
440 444
441 445 buff_experimento = (char *) malloc(7*(num_filas-3)); // num_bytes_fila*(num_filas-3);
442 446 strncpy(buff_experimento,puntero,7*(num_filas-3)); // Se carga en memoria la informacion del archivo
443 447
444 448 fclose(Archivo_Fd);
445 449
446 450 return 1;
447 451 }
448 452 }
449 453
450 454 /*
451 455 * Esta funcion recibe un numero en formato char, el dato se transforma a su equivalente en
452 456 * un numero entero, que sera usado para sacar un dato del buffer "buff_experimento", esta
453 457 * dato es el valor que se enviara al sistema de conmutacion RF para el cambio de apunte a
454 458 * traves del puerto GPIO.
455 459 */
456 460 int cambia_apuntamiento(char *puntero_char){
457 461
458 462 /*MSB-UP-LSB MSB-DOWN-LSB*/
459 463 int desplazamiento[6]={30,28,26,24,22,20}; // Defino los dezplazamientos que se aplicara
460 464 // al dato que ingresa para formar el número
461 465 // entero que se le pasara al puerto GPIO
462 466 // Estos números son los pines del puerto GPIO
463 467 // que se estan usando para el control
464 468
465 469 int puntero= atoi(puntero_char); // Se convierte a entero la direccion del puntero
466 470
467 471 int base= 7*puntero; // base= cantidad_bytes del dato x puntero
468 472 // cantidad de bytes es el numero de bytes que
469 473 printf("%s\n",puntero_char); // contiene cada dato, para este caso es 7
470 474 // porque es 6 bits de datos + 1 bit del cambio
471 475 // de linea.
472 476 char valor_char;
473 477 unsigned long valor;
474 478 unsigned long acumulado_ceros=0;
475 479 unsigned long acumulado_unos=0;
476 480
477 481 int offset; // Defino offset para el desplazamiento a traves
478 482 for(offset=0;offset<6;offset++){ // de cada dato que se obtiene del "buff_experimento"
479 483
480 484 valor_char= buff_experimento[base+offset]; // Obtengo el dato
481 485
482 486 if (valor_char == '0'){ // Obtengo el número acumulado segun sea un cero o un uno
483 487 valor= 0;
484 488 acumulado_ceros= acumulado_ceros + (1 << desplazamiento[offset]);
485 489 }else{
486 490 valor= 1;
487 491 acumulado_unos= acumulado_unos + (1 << desplazamiento[offset]);
488 492 }
489 493 }
490 494 pio_out(pioc, maskc_out, acumulado_unos, 1);
491 495 pio_out(pioc, maskc_out, acumulado_ceros, 0);
492 496
493 497 return 1;
494 498
495 499 }
496 500
497 501 /*
498 502 * Esta funcion lee "n" veces el estado del APUNTE actual y reporta
499 503 * una cadena de Verificacion.
500 504 */
501 505 char* chequeo_sistema(char *filename, char *numero_muestras){
502 506
503 507 int i;
504 508 int cnt = 0;
505 509 unsigned int entradac= 0;
506 510
507 511 char page0[250];
508 512
509 strcpy(page0,"Verificacion\n");
510 strcat(page0,parameters.ID);
511 strcat(page0,"\n------------\n");
513 /*strcpy(page0,"Verificacion\n");
514 strcat(page0,parameters.ID);*/
515 strcpy(page0,parameters.ID);
516 strcat(page0,"\n-------\n");
512 517
513 518 char page1[8];
514 519
515 520 do{
516 521 //Inicializando arreglo
517 522 for(i=0;i<6;i++)
518 523 page1[i]='0';
519 524 page1[6] = '\n';
520 525 page1[7] = '\0';
521 526 //Lectura de puerto
522 527 entradac= pio_in(piob,maskb_in);
523 528 //Dandole formato al dato
524 529 if (!(entradac & bit_up_2))
525 530 page1[0] = '1';
526 531 if (!(entradac & bit_up_1))
527 532 page1[1] = '1';
528 533 if (!(entradac & bit_up_0))
529 534 page1[2] = '1';
530 535 if (!(entradac & bit_dow_2))
531 536 page1[3] = '1';
532 537 if (!(entradac & bit_dow_1))
533 538 page1[4] = '1';
534 539 if (!(entradac & bit_dow_0))
535 540 page1[5] = '1';
536 541
537 542 strcat(page0, page1);
538 543 cnt=cnt+1;
539 544 usleep(1*1000*1000);
540 545
541 546 }while(cnt < atoi(numero_muestras));
542 547
543 548 page0[strlen(page0)] = '\0';
544 549
545 550 char *all_pages = malloc(strlen(page0)+1);
546 551 strcpy(all_pages, page0);
547 552 return all_pages;
548 553 }
549 554
550 555 /*
551 556 *
552 557 */
553 558 cmp inicializa_modulo(cmp p){
554 559 FILE *fd = fopen("configuration.txt","r");
555 560 fgets(p.ID,20,fd);
556 561 p.ID[7]='\0';
557 562 fgets(p.param2,20,fd);
558 563 p.param2[10]='\0';
559 564 fgets(p.param3,20,fd);
560 565 p.param3[10]='\0';
561 566 fgets(p.param4,20,fd);
562 567 p.param4[10]='\0';
563 568 fclose(fd);
564 569 return p;
565 570 }
566 571
567 572 /*
568 573 *
569 574 */
570 575 void intToStr( int number, char* str )
571 576
572 577 {
573 578 int index = 0;
574 579
575 580 while( number > 0 )
576 581 {
577 582 int digit = number%10;
578 583 str[index++] = digit + '0';
579 584 number /= 10;
580 585 }
581 586 str[index] = '\0';
582 587 //Adding zero to the left
583 588 int n= strlen(str);
584 589 if (n == 1) {
585 590 strcat(str,"00000");
586 591 index = index + 5;
587 592 }else if(n == 2){
588 593 strcat(str,"0000");
589 594 index = index + 4;
590 595 }else if(n == 3){
591 596 strcat(str,"000");
592 597 index = index + 3;
593 598 }else if(n == 4){
594 599 strcat(str,"00");
595 600 index = index + 2;
596 601 }else if(n == 5){
597 602 strcat(str,"0");
598 603 index = index + 1;
599 604 }
600 605 //Now reverse the numbers in the string.
601 606 int position;
602 607 for( position = 0; position <= (index-1)/2; ++position )
603 608 {
604 609 char tmp = str[position];
605 610 str[position] = str[(index-1)-position];
606 611 str[(index-1)-position] = tmp;
607 612 }
608 613 }
609 614
610 615
611 616 //*****************************************************************
612 617 //ABS_monitoreo es la funci�n principal del proyecto ABS_Monitoreo.
613 618 //Esta funci�n es la que se debe agregar en otros c�digos.
614 619 //*****************************************************************
615 620 int ABS_monitoreo(int sel_atenuador, int sel_calibracion, float umbral, int pulsewidth){
616 621
617 622 //local variables
618 623 AT91S_PIO *pioc;
619 624 pioc = pio_map(PIOC_BASE);
620 625 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
621 626 unsigned int mask_sel_atenuacion =PC5;
622 627 unsigned int mask_sel_calibracion =PC6;
623 628 AT91S_ADC *padc;
624 629 AT91S_ADC *padd;
625 630 FILE *fp;
626 631 long int results1[NSAMPLES], results2[NSAMPLES], results3[NSAMPLES], results4[NSAMPLES];
627 632 unsigned int i=0;
628 633 char fname[FNAMELEN];
629 634 int j=0;
630 635 time_t now;
631 636 FILE *archivo;
632 637 float phase1;
633 638 float phase2;
634 639 //system("./map_clock");
635 640
636 641 if (configCLK() == 1)
637 642 printf("clock ADC enable.\n");
638 643
639 644
640 645 //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.
641 646 pio_enable(pioc, mask_sel_canal);
642 647 pio_enable(pioc, mask_sel_atenuacion);
643 648 pio_enable(pioc, mask_sel_calibracion);
644 649 pio_output_enable(pioc, mask_sel_canal); //configurar pc4 como salida
645 650 pio_output_enable(pioc, mask_sel_atenuacion); //configurar pc5 como salida
646 651 pio_output_enable(pioc, mask_sel_calibracion); //configurar pc6 como salida
647 652
648 653
649 654 //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.
650 655 if ( sel_atenuador == 1)
651 656 pio_out(pioc, mask_sel_atenuacion, sel_atenuador,1);
652 657 else
653 658 pio_out(pioc, mask_sel_atenuacion, sel_atenuador,0);
654 659 if ( sel_calibracion == 1)
655 660 pio_out(pioc, mask_sel_calibracion, sel_calibracion,1);
656 661 else
657 662 pio_out(pioc, mask_sel_calibracion, sel_calibracion,0);
658 663
659 664
660 665 strcpy (fname, "/mnt/sd/archivos/absmonitoreo.txt"); //Direcci�n y nombre del archivo donde se desea guardar los datos.
661 666
662 667 if (fExists(fname)==0){ //si el archivo no existe, crea uno y le asigna el titulo
663 668 archivo = fopen(fname,"a+");
664 669 fprintf(archivo,"%s"," Registro de datos del ABS Control \n");
665 670 fprintf(archivo,"%s"," Fecha y hora Fase UP Fase DOWN\n");
666 671 fclose(archivo);
667 672 }
668 673
669 674
670 675 //configure ADC Settings
671 676 padc=configADC1();
672 677 padd=configADC2();
673 678
674 679 while (1){
675 680
676 681 ENABLE_CHANNEL(padc, ADC_CH0+ADC_CH1);
677 682 printf("\nAdquiriendo datos...\n"); //Indica en el terminal que se est�n adquiriendo datos (muestreando la se�al).
678 683
679 684
680 685 now = time(0); //Get current Time for File Name
681 686
682 687
683 688 //Se pone la salida de selecci�n de canal para seleccionar el canal 1 del detector de fase
684 689 // pio_out(pioc, mask_sel_canal, 0,1);
685 690 pio_out(pioc, mask_sel_canal, 0,1);
686 691
687 692
688 693 //Se toman muestras para el canal 1 del detector de fase
689 694 while(1){
690 695 for(i=0; i < NSAMPLES; i++){
691 696
692 697 ADC_INIT(padc);
693 698 results1[i] = GET_ADC0(padc);
694 699 results2[i] = GET_ADC1(padd);
695 700 }
696 701
697 702
698 703 if (checkTx(results1, results2, umbral, pulsewidth)==1){ //Se verifica que las muestras tomadas del canal 1 del datector de fase //correspondan a un pulso.
699 704 break;
700 705 }
701 706 }
702 707
703 708
704 709 //Se pone la salida de selecci�n de canal para seleccionar el canal 2 del detector de fase
705 710 pio_out(pioc, mask_sel_canal, 1,1);
706 711
707 712
708 713
709 714 //Setoman muestras para el canal 2 del detector de fase
710 715 while(1){
711 716 for(i=0; i < NSAMPLES; i++){
712 717
713 718 ADC_INIT(padc);
714 719 results3[i] = GET_ADC0(padc);
715 720 results4[i] = GET_ADC1(padd);
716 721 }
717 722
718 723 if (checkTx(results3, results4, umbral, pulsewidth)==1){ //Se verifica que las muestras tomadas del canal 2 del detector de fase //correspondan a un pulso.
719 724 break;
720 725 }
721 726 }
722 727
723 728
724 729 //Una vez que se ha encontrado un pulso en cada canal, se calcula la fase de ambos.
725 730
726 731 phase1 = getPhase(results1, results2); //Calcular la fase del canal 1 del detector de fase.
727 732 phase2 = getPhase(results3, results4); //Calcular la fase del canal 2 del detector de fase.
728 733 //create Output File
729 734
730 735 strcpy (fname, "/mnt/sd/archivos/absmonitoreo.txt");
731 736 printf("\nTerminada la prueba # %d \n", j++);
732 737 fp=create_Output(fname, now); //Coloca la fecha y la hora en el archivo de texto
733 738 printf("mediana ch1 = %1.2f\n", phase1); //muestra resultado en terminal
734 739 printf("mediana ch2 = %1.2f\n", phase2); //muestra resultado en terminal
735 740 writeOutput(phase1, fp); //graba el resultado en el archivo de texto
736 741 writeOutput(phase2, fp); //graba el resultado en el archivo de texto
737 742 fprintf(fp, "\n"); //Pasa a la siguiente l�nea del archivo de texto
738 743 fclose(fp);
739 744 printf("Resultado guardado en %s \n", fname);
740 745
741 746 sleep(1);
742 747
743 748 }
744 749 return 0;
745 750 }
746 751 /*=============================================================================
747 752 Function definitions
748 753 =============================================================================*/
749 754
750 755 // Configures ADC registers in order to get a sample every 10us
751 756 AT91S_ADC * configADC1(void){
752 757 //Variables a usar:
753 758 unsigned int maskc_adc =PC0; //Usamos ADC0 y ADC1
754 759
755 760 //configuro pin:
756 761 AT91S_PIO *pioc;
757 762 pioc = pio_map(PIOC_BASE);
758 763 pin_adc_enable(pioc,maskc_adc); //Habilitamos PC0 para usar con ADC0 y 1
759 764 pio_disable_irq(pioc, maskc_adc);
760 765 pio_disable_multiple_driver(pioc, maskc_adc);
761 766 pio_disable_pull_ups(pioc, maskc_adc);
762 767 pio_input_enable(pioc, maskc_adc);
763 768
764 769
765 770 //Configuro el ADC:
766 771 AT91S_ADC *padc;
767 772
768 773 padc = adc_map1(ADC_BASE);
769 774
770 775 //clock ADC = 1MHz
771 776 //time startup = 8us
772 777 //time sample and hold = 2us
773 778 // hold
774 779 // ___________
775 780 // start ___________| |___________
776 781 //
777 782 // | --1.2us-- | --0.15us-- |
778 783 //ADC_RESET(padc);
779 784 CONFIG_ADC(padc,ADC_TRGEN_DIS | ADC_RES_10BIT | ADC_SLEEP_NORMAL_MODE | ADC_PRESCAL | ADC_STARTUP | ADC_SHTIM);
780 785 ENABLE_CHANNEL(padc,ADC_CH0); //habilito canal 0
781 786
782 787
783 788 return padc;
784 789 }
785 790
786 791 AT91S_ADC * configADC2(void){
787 792 //Variables a usar:
788 793 unsigned int maskc_adc =PC1; //Usamos ADC0 y ADC1
789 794
790 795 //configuro pin:
791 796 AT91S_PIO *piod;
792 797 piod = pio_map(PIOC_BASE);
793 798 pin_adc_enable(piod,maskc_adc); //Habilitamos PC0 para usar con ADC0 y 1
794 799 pio_disable_irq(piod, maskc_adc);
795 800 pio_disable_multiple_driver(piod, maskc_adc);
796 801 pio_disable_pull_ups(piod, maskc_adc);
797 802 pio_input_enable(piod, maskc_adc);
798 803
799 804 //Configuro el ADC:
800 805 AT91S_ADC *padd;
801 806
802 807 padd = adc_map1(ADC_BASE);
803 808
804 809 //clock ADC = 1MHz
805 810 //time startup = 8us
806 811 //time sample and hold = 2us
807 812 // hold
808 813 // ___________
809 814 // start ___________| |___________
810 815 //
811 816 // | --1.2us-- | --0.15us-- |
812 817 //ADC_RESET(padc);
813 818 CONFIG_ADC(padd,ADC_TRGEN_DIS | ADC_RES_10BIT | ADC_SLEEP_NORMAL_MODE | ADC_PRESCAL | ADC_STARTUP | ADC_SHTIM);
814 819 ENABLE_CHANNEL(padd,ADC_CH1); //habilito canal 1
815 820 return padd;
816 821 }
817 822
818 823
819 824 //++++++++++++++++++++
820 825
821 826 //creats the output file with a timestamp in the name
822 827 FILE * create_Output(char *fname, time_t rawtime){
823 828 FILE *file;
824 829 char timestamp[80];//, counter[5]="dcv";
825 830 //char str[4];
826 831 struct tm * timeinfo;
827 832
828 833 //format time
829 834 timeinfo = localtime ( &rawtime );
830 835 strftime (timestamp,sizeof(timestamp),"%a %y-%m-%d %H:%M:%S %Z",timeinfo);
831 836
832 837
833 838 //Creates the file name out of the #define parameters
834 839
835 840 strcpy (fname, "/mnt/sd/archivos/absmonitoreo.txt");
836 841 file = fopen(fname,"a+");
837 842 fprintf(file,"%s", timestamp);
838 843 //printf("\nTerminada la prueba # %d. Guardando resultado en %s\n",r, fname);
839 844 //printf("\nTerminada la prueba # %d/%d. Writing data to the file %s\n",r+1 , REP, fname);
840 845 //printf("\nAAAAAAAAAA %d...%s\n", counter[1], fname);
841 846 // return file pointer
842 847 return file;
843 848 }
844 849
845 850 //++++++++++++++++++++
846 851
847 852 //tests if a file already exists. returns 1 if it exists and 0 if it doesn't
848 853
849 854
850 855
851 856 //Funci�n checkTx verifica que la se�al muestreada corresponda a un pulso.
852 857 //results1 y results2 son los arreglos que contienen los datos muestreados por ambos canales del ADC del embebido.
853 858 //umbral indica qu� valor debe superar una muestra para considerarla un posible pulso o pico.
854 859 //pulsewidth indica cu�ntas muestras consecutivas deben superar el umbral para que se considere que se ha detectado un pulso.
855 860 int checkTx(long int results1[],long int results2[], float umbral, int pulsewidth){
856 861
857 862 int i, cont;
858 863 float z[NSAMPLES], sum, avg;
859 864 int isSignal, pulse;
860 865
861 866 for(i=0;i<NSAMPLES;i++){
862 867
863 868 z[i] =sqrt(1.0*results1[i]*results1[i]+1.0*results2[i]*results2[i]);
864 869 }
865 870
866 871 pulse = 0;
867 872 isSignal = 0;
868 873 cont =0;
869 874
870 875 sum = 0;
871 876 for(i=0;i<NSAMPLES;i++){
872 877
873 878 sum += z[i];
874 879 avg = sum/(i+1);
875 880 if ((z[i] - avg) > umbral){
876 881 if (isSignal == 1){
877 882 cont += 1;
878 883 }
879 884 if (cont == pulsewidth){
880 885 pulse = 1;
881 886 break;
882 887 }
883 888 isSignal = 1;
884 889 continue;
885 890 isSignal = 0;
886 891 cont = 0;
887 892 }
888 893 }
889 894
890 895 return pulse; //devuelve un entero: 1 si se ha detectado pulso, de lo contrario, 0.
891 896 }
892 897
893 898
894 899 int fExists(char * fname){
895 900 FILE * file;
896 901
897 902 file = fopen (fname, "r");
898 903 if (file == NULL)
899 904 {
900 905 return 0;
901 906 }
902 907 fclose(file);
903 908 return 1;
904 909 }
905 910
906 911
907 912 //Funci�n que calcula la mediana de un conjunto de muestras
908 913 double mediana(long int *results,unsigned int cuenta){
909 914 unsigned int i=0,j=0,aux=0;
910 915
911 916 double median=0;
912 917 /*Calculo mediana */
913 918
914 919 for(i=0;i<cuenta-1;i++){
915 920 for (j=i+1;j<cuenta;j++){
916 921 if(results[i]>results[j] ){
917 922
918 923 aux=results[i];
919 924 results[i]=results[j];
920 925 results[j]=aux;
921 926
922 927 }
923 928 }
924 929
925 930 }
926 931 median=results[cuenta/2];
927 932 return median;
928 933 }
929 934
930 935
931 936
932 937 //Funci�n que halla la fase de la se�al.
933 938 //Tiene como entradas las muestras correspondientes a la parte real e imaginaria de la se�al.
934 939 float getPhase(long int results1[],long int results2[]){
935 940
936 941 unsigned int count=0, i=0,umbral=1000;
937 942 //long int results1[];
938 943 //long int results2[];
939 944 long int power[NSAMPLES];
940 945 long int sumI=0,sumQ=0,I[NSAMPLES], Q[NSAMPLES],II[NSAMPLES], QQ[NSAMPLES];
941 946 double median1=0,median2=0;
942 947 long int promedioI=0,promedioQ=0;/*Calculo mediana 1*/
943 948 float resultado=0;
944 949
945 950 for(i=0;i<NSAMPLES;i++){
946 951
947 952 I[i] =results1[i];
948 953 Q[i] =results2[i];
949 954 }
950 955
951 956 /*Calculo mediana 1*/
952 957 median1=mediana(I,NSAMPLES);
953 958
954 959 /*Calculo mediana 2*/
955 960 median2=mediana(Q,NSAMPLES);
956 961
957 962
958 963
959 964
960 965
961 966
962 967 for(i=0;i<NSAMPLES;i++){
963 968
964 969 I[i] =results1[i];
965 970 Q[i] =results2[i];
966 971
967 972 }
968 973
969 974
970 975
971 976 for(i = 0; i < NSAMPLES ; i++){
972 977
973 978 I[i]=(I[i]-median1);
974 979 Q[i]=(Q[i]-median2);
975 980
976 981 }
977 982
978 983 for(i = 0; i < NSAMPLES ; i++){
979 984
980 985 power[i]=I[i]*I[i]+Q[i]*Q[i];
981 986
982 987 if(power[i] > umbral)
983 988 {
984 989
985 990 II[count]=I[i];
986 991 QQ[count]=Q[i];
987 992 count=count+1;
988 993
989 994 }
990 995
991 996 }
992 997
993 998 for(i = 0; i < count ; i++){
994 999
995 1000 sumI=sumI+II[i];
996 1001 sumQ=sumQ+QQ[i];
997 1002
998 1003 }
999 1004
1000 1005 promedioI=sumI;
1001 1006 promedioQ=sumQ;
1002 1007
1003 1008 resultado = atan2(1.0*promedioI,1.0*promedioQ)*180/3.1416+62-44;
1004 1009
1005 1010
1006 1011 return resultado;
1007 1012
1008 1013 }
1009 1014
1010 1015
1011 1016
1012 1017 //Funci�n que muestra la fase detectada en el terminal y tambi�n la graba en el archivo de texto.
1013 1018 void writeOutput(float resultado, FILE * output){
1014 1019
1015 1020
1016 1021 //
1017 1022
1018 1023 fprintf(output," %1.2f ",resultado); //graba resultado en archivo .txt
1019 1024 //
1020 1025
1021 1026 }
1022 1027
1023 1028 int configCLK(){
1024 1029 //configuro pin:
1025 1030 AT91S_PMC *sys_clock;
1026 1031 sys_clock = clock_map(CLOCK_BASE);
1027 1032 enable_clock_adc(sys_clock);
1028 1033 //printf("clock ADC enable.\n");
1029 1034 return 1;
1030 1035 }
General Comments 0
You need to be logged in to leave comments. Login now