##// END OF EJS Templates

File last commit:

r246:247
r246:247
Show More
ServidorTCP.c
1287 lines | 34.1 KiB | text/x-c | CLexer
/*
* 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 <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>
#include <time.h>
#include <math.h>
#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;
//char *cbeam = malloc(7);
char *cbeam = 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);
char *chequeo_sistema2();
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 if(strcmp(cmd,"MNTR") == 0){
if(strcmp(rx_data,"0") == 0){
//Only current beam is requested
tx_data = malloc(50);
strcpy(tx_data,parameters.ID);
strcat(tx_data,"\n-------\n");
strcat(tx_data,cbeam);
printf("%s\n",tx_data);
}
else if(strcmp(rx_data,"1") == 0){
//Only relay status is requested
tx_data = malloc(50);
strcpy(tx_data,parameters.ID);
strcat(tx_data,"\n-------\n");
strcat(tx_data,chequeo_sistema2());
printf("%s\n",tx_data);
}
else if(strcmp(rx_data,"2") == 0){
//Only phase is requested
tx_data = malloc(100);
strcpy(tx_data,parameters.ID);
strcat(tx_data,"\n-------\n");
strcat(tx_data,ABS_monitoreo(1, 0, 50, 10));
printf("%s\n",tx_data);
}
else if(strcmp(rx_data,"3") == 0){
//Current beam and relay status is requested
tx_data = malloc(100);
strcpy(tx_data,parameters.ID);
strcat(tx_data,"\n-------\n");
strcat(tx_data,cbeam);
strcat(tx_data,chequeo_sistema2());
printf("%s\n",tx_data);
}
else{
//Current beam, relays status and phase is requested
tx_data = malloc(100);
strcpy(tx_data,parameters.ID);
strcat(tx_data,"\n-------\n");
strcat(tx_data,cbeam);
strcat(tx_data,chequeo_sistema2());
strcat(tx_data,ABS_monitoreo(1, 0, 50, 10));
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
// 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]);
}
}
//
char cero = '\0';
char enter = '\n';
cbeam = malloc(8);
sprintf(cbeam,"%c%c%c%c%c%c%c%c",buff_experimento[base],buff_experimento[base+1],buff_experimento[base+2],buff_experimento[base+3],buff_experimento[base+4],buff_experimento[base+5],enter,cero);
printf("Beam: %s : %s\n",puntero_char,cbeam);
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;
}
char* chequeo_sistema2(){
int i;
unsigned int entradac= 0;
char page1[8];
//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';
char *all_pages = malloc(strlen(page1)+1);
strcpy(all_pages, page1);
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\n%1.2f\n",phase1, phase2);
page1[strlen(page1)]='\0';
// strcat(page0,page1);
// char *all_pages = malloc(strlen(page0)+1);
char *all_pages = malloc(strlen(page1)+1);
strcpy(all_pages, page1);
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<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;
}