#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);
}