#Develp by Jhoberg Quevedo #email: jrquevedor@gmail.com #include "lwip/debug.h" #include "lwip/stats.h" #include "lwip/tcp.h" #include #include #include #include #include #include #include #include #include #include #include #include "html.h" #define MAXSIZETCP 2048 // // // volatile char * cadenainfo; volatile char * apcomando; char txdata [MAXSIZETCP]; char info[512]; //******************************************Definicion variables eCos #define STACK_SIZE 0x800 cyg_alarm_t test_timer1; static cyg_thread thread_s[1]; cyg_thread_entry_t samples_program; cyg_handle_t samples_thread; cyg_handle_t http_thread; static char stack[1][STACK_SIZE]; cyg_mutex_t adcblock; cyg_handle_t handle_ADC_ISR0; cyg_interrupt intrADC; cyg_sem_t semaforo_ADC,semaforo_nsamples; cyg_io_handle_t handle_IO; int aux=0; //******************************************fin Definicion variables eCos #define LED_1 (1<<16) #define LED_2 (1<<17) #define LED_3 (1<<18) int axgnd=0; int axgndi=0; int axmin=0; int axmax=0; double *toppw; double axenergy; float jh=0; float jh2=0; float jh3=0; float axjh=0; //******************************************definicion de la clase ADC ANALOG DEVICE en C #define NSAMPLES 64 #define FAMPLES 3840 static cyg_uint32 ADRMEMORYK=0x297; int Mapear(void); bool ConvertionStart(void); bool ReadAdc(unsigned short *,cyg_uint32 *); bool setChanel(int); bool fpcalc(float axntfpv,float axntfpi); int Mapear(void) { HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_PDR ,AT91_PIO_PSR_NCS3); HAL_WRITE_UINT32(AT91_EBI + AT91_EBI_MCR,AT91_EBI_MCR_ALE_8M|(0<<4) ); HAL_WRITE_UINT32(AT91_EBI + AT91_EBI_CSR1, AT91_EBI_CSR_DBW_16 | AT91_EBI_CSR_NWS_8 | AT91_EBI_CSR_WSE | AT91_EBI_CSR_PAGES_1M | AT91_EBI_CSR_TDF_1 | AT91_EBI_CSR_CSEN | (ADRMEMORYK<<20) ); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_PER , AT91_PIO_PSR_TIOA1|AT91_PIO_PSR_P23|AT91_PIO_PSR_P24 ); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_OER, AT91_PIO_PSR_TIOA1|AT91_PIO_PSR_P23|AT91_PIO_PSR_P24 ); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_SODR, AT91_PIO_PSR_TIOA1); //definicion de los pines para escojer un canal de conversion defaul ch3 HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_SODR, AT91_PIO_PSR_P23); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_CODR, AT91_PIO_PSR_P24); return 1; //0,0 -> B //1,0 -> Voltaje } bool ConvertionStart(void) { HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_CODR, AT91_PIO_PSR_TIOA1); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_SODR, AT91_PIO_PSR_TIOA1); return 1; } bool ReadAdc(cyg_uint16 *Datoax, cyg_uint32 *address) { HAL_READ_UINT16((*address<<20) ,*Datoax ); return 1; } bool setChanel(int chop) { switch(chop) { case 0:{ HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_CODR, AT91_PIO_PSR_P23); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_CODR, AT91_PIO_PSR_P24); //voltaje break;} case 1:{ HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_CODR, AT91_PIO_PSR_P23); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_SODR, AT91_PIO_PSR_P24); break;} case 2:{ HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_SODR, AT91_PIO_PSR_P23); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_CODR, AT91_PIO_PSR_P24); //corriente break;} case 3:{ HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_SODR, AT91_PIO_PSR_P23); HAL_WRITE_UINT32(AT91_PIO + AT91_PIO_SODR, AT91_PIO_PSR_P24); break;} } return 1; } typedef struct adc_7654 { volatile cyg_uint32 ADRMEMORY; volatile cyg_uint16 Dato; volatile int samplesH[NSAMPLES]; int *i; volatile int *Samples[NSAMPLES]; char *cDato; char *cSamples; int topsamples; int numsample; unsigned long energysample; float energytop; double *EnergyDato; int rateenergy; int MaxV; int MinV; volatile unsigned int *MaxI; volatile unsigned int *MinI; volatile float instantVol; volatile float instantCur; int Comdato; int ntfpv; int ntfpi; float fp; int Comando; int promedioH; int promedioV; int (* apMapear)(void); bool (* apConvertionStart)(void); bool (* apReadAdc)(cyg_uint16 *,cyg_uint32 *); bool (* apsetChanel)(int); }; volatile struct adc_7654 adc,axadc; bool fpcalc(float axntfpv,float axntfpi) { if(axntfpv>axntfpi) { axntfpv=axntfpv-axntfpi; axntfpi=axntfpv*9817477E-8; axntfpv=cos(axntfpi); axadc.fp=axntfpv; } else{ axntfpv=axntfpi-axntfpv; axntfpi=axntfpv*9817477E-8; axntfpv=cos(axntfpi); axadc.fp=axntfpv; } return 1; } cyg_uint32 fun_isr0 (cyg_vector_t vector, cyg_addrword_t data ) { cyg_uint32 resultPIO; // HAL_WRITE_UINT32( AT91_PIO + AT91_PIO_SODR ,LED_2 ); HAL_READ_UINT32(AT91_PIO + AT91_PIO_ISR, resultPIO); cyg_interrupt_mask(vector); cyg_interrupt_acknowledge(vector); return (CYG_ISR_HANDLED | CYG_ISR_CALL_DSR); } void fun_dsr0(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){ cyg_interrupt_unmask(vector); } // funcion de muestreo, con frecuencia variable void bitAdc_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) { axmax=0; axmin=0; axgnd=0; jh=0; jh2=0; jh3=0; HAL_WRITE_UINT32( AT91_PIO + AT91_PIO_SODR ,LED_2 ); cyg_scheduler_lock(); cyg_mutex_lock(&adcblock); if(adc.numsample>NSAMPLES) { HAL_WRITE_UINT32( AT91_PIO + AT91_PIO_CODR ,LED_2 ); if(axadc.Comando==0) axadc=(struct adc_7654)adc; cyg_semaphore_post(&semaforo_nsamples); if((*adc.EnergyDato)0) adc.instantVol=jh2*jh; else adc.instantVol=120E0; axmax=(*adc.MaxI); axmin=(*adc.MinI); // axgnd=adc.promedioH; //axgnd=(int)(axgnd/NSAMPLES); axgnd=axmin+(((axmax)-(axmin))/2 ); //para calcuar con dcgnd variable jh2=(float)( axmax - axgnd); jh=4565E-6; if( jh2 > 0) jh3=jh2*jh; else jh3=0; if(jh3>0) { adc.instantCur=jh3; jh=(adc.instantVol*(jh3)); *toppw+=jh; *adc.EnergyDato=*toppw; } else{ adc.instantCur=0E0; adc.instantVol=120E0; } adc.MaxV=0; *adc.MinI=0xFFFF; *adc.MaxI=0; adc.MinV=0xFFFF; adc.numsample=0; adc.promedioH=0; adc.promedioV=0; adc.energysample++; }else{ adc.Comdato=1; } }else { //dato de B adc.apsetChanel(2); adc.apConvertionStart(); adc.apReadAdc(&adc.Dato,adc.ADRMEMORY); adc.samplesH[adc.numsample]=adc.Dato; adc.promedioH+=adc.samplesH[adc.numsample]; if(*adc.MaxIadc.samplesH[adc.numsample]) *adc.MinI=(unsigned int)adc.samplesH[adc.numsample]; adc.i=7; //dato de V adc.apsetChanel(0); adc.apConvertionStart(); adc.apReadAdc(&adc.Dato,adc.ADRMEMORY); adc.Samples[adc.numsample]=adc.Dato; adc.promedioV+=(*adc.Samples[adc.numsample]); if(adc.MaxVadc.Samples[adc.numsample]) { adc.MinV=adc.Samples[adc.numsample]; adc.ntfpv=adc.numsample; } adc.numsample++; } cyg_mutex_unlock(&adcblock); cyg_scheduler_unlock(); } void samples_program(cyg_addrword_t data) { int message = (int) data; int delay; int n,x; char output; cyg_handle_t test_counterH, system_clockH, test_alarmH; cyg_tick_count_t ticks; cyg_alarm test_alarm; cyg_handle_t tiempo_real; unsigned how_many_alarms = 0, prev_alarms = 0, tmp_how_many; system_clockH = cyg_real_time_clock(); cyg_clock_to_counter(system_clockH, &test_counterH); cyg_alarm_create(test_counterH, bitAdc_alarm_func, (cyg_addrword_t) &how_many_alarms , &test_alarmH, &test_alarm); cyg_alarm_initialize(test_alarmH, cyg_current_time()+1, 2); for (;;) { } } // fin frecuencia de muestreo //******************************************fin de la clase ADC de ANALOG DEVICE en C struct http_state { char *file; u32_t left; u8_t retries; }; //----------------------------------------------------------------------------------- static void conn_err(void *arg, err_t err) { struct http_state *hs; hs = arg; mem_free(hs); } //----------------------------------------------------------------------------------- static void close_conn(struct tcp_pcb *pcb, struct http_state *hs) { tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); mem_free(hs); tcp_close(pcb); } //----------------------------------------------------------------------------------- static void send_data(struct tcp_pcb *pcb, struct http_state *hs) { err_t err; u16_t len; // We cannot send more data than space available in the send // buffer. if(tcp_sndbuf(pcb) < hs->left) { len = tcp_sndbuf(pcb); } else { len = hs->left; } do { err = tcp_write(pcb, hs->file, len, 0); if(err == ERR_MEM) { len /= 2; } } while(err == ERR_MEM && len > 1); if(err == ERR_OK) { hs->file += len; hs->left -= len; } } //----------------------------------------------------------------------------------- static err_t http_poll(void *arg, struct tcp_pcb *pcb) { struct http_state *hs; hs = arg; // printf("Polll\n"); if(hs == NULL) { // printf("Null, close\n"); tcp_abort(pcb); return ERR_ABRT; } else { ++hs->retries; if(hs->retries == 4) { tcp_abort(pcb); return ERR_ABRT; } send_data(pcb, hs); } return ERR_OK; } //----------------------------------------------------------------------------------- static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { struct http_state *hs; hs = arg; hs->retries = 0; if(hs->left > 0) { send_data(pcb, hs); } else { close_conn(pcb, hs); } return ERR_OK; } // int reqtypehttp(char *data) { int i,aux,j; char tipo[20]; int vartop,varmem,var; if(strncmp("GET / ",data,6)) { aux=0; while( data[aux+5] != NULL ) { if( ((char *)data+5)[aux]==' ' ) break; else tipo[aux]=((char *)data+5)[aux]; aux++; } }else { cyg_semaphore_wait(&semaforo_nsamples); axadc.Comando=1; j=sizeof(vpage_index); memcpy(txdata,vpage_index,j); j=strlen(txdata); fpcalc(axadc.ntfpv,axadc.ntfpi); // axenergy=(double)*axadc.EnergyDato; //axenergy=axenergy/21E6; sprintf(info,"

Datos remotos

Energia%f_Kw*h
Vinsta:%f_V
Iinsta:%f_A
F.P%f
Ciclos%lu

",*axadc.EnergyDato,axadc.instantCur,axadc.instantVol,axadc.fp,axadc.energysample); j=strlen(txdata); i=strlen(info); memcpy(&(txdata[j]),info,i); /* vartop=0; for(var=0;vartot_len); if(hs->file == NULL) { data = p->payload; sizetx=reqtypehttp(data); hs->file = &txdata; hs->left = sizetx; pbuf_free(p); send_data(pcb, hs); tcp_sent(pcb, http_sent); } else { pbuf_free(p); close_conn(pcb, hs); } } else { pbuf_free(p); } if(err == ERR_OK && p == NULL) { close_conn(pcb, hs); } return ERR_OK; } //----------------------------------------------------------------------------------- static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct http_state *hs; tcp_setprio(pcb, TCP_PRIO_MIN); // Allocate memory for the structure that holds the state of the // connection. hs = mem_malloc(sizeof(struct http_state)); if(hs == NULL) { return ERR_MEM; } // Initialize the structure. hs->file = NULL; hs->left = 0; hs->retries = 0; // Tell TCP that this is the structure we wish to be passed for our // callbacks. tcp_arg(pcb, hs); // Tell TCP that we wish to be informed of incoming data by a call // to the http_recv() function. tcp_recv(pcb, http_recv); tcp_err(pcb, conn_err); tcp_poll(pcb, http_poll, 4); return ERR_OK; } //----------------------------------------------------------------------------------- void httpd_init(void *arg) { struct tcp_pcb *pcb; pcb = tcp_new(); tcp_bind(pcb, IP_ADDR_ANY, 80); pcb = tcp_listen(pcb); tcp_accept(pcb, http_accept); while(1) cyg_thread_delay(1000); } // funcin principal void webserver(cyg_addrword_t p) { lwip_init(); sys_thread_new(httpd_init, (void*)"httpd",7); } void cyg_user_start(void) { //inicializacio de la clase adc.topsamples=NSAMPLES; adc.numsample=0; adc.energysample=0; adc.energytop=216E6; //1KW/h adc.cDato=(char *)malloc(sizeof(char [4])); adc.apMapear=Mapear; adc.apConvertionStart=ConvertionStart; adc.apReadAdc=ReadAdc; adc.apsetChanel=setChanel; adc.ADRMEMORY=&ADRMEMORYK; adc.apMapear(); adc.Comdato=0; adc.EnergyDato=malloc(sizeof(double *));; adc.rateenergy=10; adc.MaxI=malloc(sizeof(int *)); adc.MinI=malloc(sizeof(int *)); *adc.MaxI=0; *adc.MinI=0xFFFF; adc.instantVol=0; adc.instantCur=0; adc.ntfpi=0; adc.ntfpv=0; adc.fp=1; adc.Comando=0; adc.promedioH=0; adc.promedioV=0; toppw=malloc(sizeof(float *)); *toppw=0; apcomando=malloc(sizeof(char *[8])); cadenainfo=malloc(sizeof(char *[100])); //fin de inicializacion cyg_mutex_init(&adcblock); cyg_semaphore_init(&semaforo_nsamples,0); cyg_semaphore_init(&semaforo_ADC,0); cyg_thread_create(10, samples_program, (cyg_addrword_t) 0, "Hilo para AD7654 de ANALOG", (void *) stack[0],STACK_SIZE, &samples_thread,&thread_s[0]); cyg_thread_create(10,webserver,0, "thread", &stack[1],STACK_SIZE, &http_thread,&thread_s[1]); cyg_thread_resume(http_thread); cyg_thread_resume(samples_thread); }