#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <math.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "dio.h"
#include "group.h"

#define TRUE 1
#define MAP_ADDRESS (31*0x100000)  /* 1 mb less than total ram */
#define BYTE unsigned char
#define WORD unsigned short
#define LONG unsigned long

/* Forward Declarations */
 
char *DevName = "/dev/dio48H_1A";
char DevNameIO[20];
int  Mode = 0;
int  Status;
int  mfd;
BYTE bReg;

int x=0; int y=0; int z=0; // group usleep params
int cnt = 0; // global count
int g_cnt = 0; // group count
int mag; // magnitude
int t_last; 
int init = 0;
int i=0;	

int fd_1A, fd_1B, fd_1C;
int fd_2A, fd_2B, fd_2C;
unsigned short value;

typedef struct
{
    unsigned short     reg[512];
    float              alg[512];
    int		       flags;
} LMAP;

LMAP *mapp;

/* Forward Declarations */

void setup_io(void);
void close_io(void);
void write_io(void);
void solve(void);
void set_o(short reg,short bit);
void clr_o(short reg,short bit);

void power(void);
void pump(void);
void state(void);
void fileio(void);
void pwave(int, int, int);
void group1(int, int, int);
void group2(int, int, int);
void group3(int, int, int);
void group4(int, int, int);
void powerr(void);
void pumpr(void);
void zpp(void);          
int seis(int);          
void shutdown(void);

main(int argc,char *argv[])
{
    if(( mfd = open("/dev/mem",O_RDWR)) < 0)
    {
        perror("dev/mem open failed");
        exit(1);
    }
    mapp = (LMAP *) mmap( 0,sizeof(LMAP),PROT_READ | PROT_WRITE,MAP_SHARED,mfd,MAP_ADDRESS);
    if(MAP_FAILED == mmap)
    {
        perror("mmap failed");
        exit(1);
    }
    close(mfd);

    // mag = seis(mag);

    setup_io();
    mapp->flags = 0;

    while( TRUE )
	{
        while(mapp->flags != 0) ;
	mapp->flags = 1;
	// printf("\n\tPRE - cnt: %d, g_cnt: %d\n", cnt, g_cnt); 
	solve();   
        write_io();
        mapp->flags = 0;
        usleep(SCAN_RATE);
	    cnt++; 
	// printf("\tPOST - cnt: %d\n", cnt); 
    }
}

void setup_io(void)
{
    strcpy(DevNameIO, "/dev/dio48H_1A");
    if ((fd_1A = open(DevNameIO, O_RDWR )) < 0) 
    {
        perror("DevNameIO");
        printf("error opening device %s\n", DevNameIO);
        exit(2);
    }
    strcpy(DevNameIO, "/dev/dio48H_1B");
    if ((fd_1B = open(DevNameIO, O_RDWR )) < 0) 
    {
        perror(DevNameIO);
        printf("error opening device %s\n", DevNameIO);
        exit(2);
    }
    strcpy(DevNameIO, "/dev/dio48H_1C");
    if ((fd_1C = open(DevNameIO, O_RDWR )) < 0) 
    {
        perror(DevNameIO);
        printf("error opening device %s\n", DevNameIO);
        exit(2);
    }

    strcpy(DevNameIO, "/dev/dio48H_2A");
    if ((fd_2A = open(DevNameIO, O_RDWR )) < 0) 
    {
        perror("DevNameIO");
        printf("error opening device %s\n", DevNameIO);
        exit(2);
    }
    strcpy(DevNameIO, "/dev/dio48H_2B");
    if ((fd_2B = open(DevNameIO, O_RDWR )) < 0) 
    {
        perror(DevNameIO);
        printf("error opening device %s\n", DevNameIO);
        exit(2);
    }
    strcpy(DevNameIO, "/dev/dio48H_2C");
    if ((fd_2C = open(DevNameIO, O_RDWR )) < 0) 
    {
        perror(DevNameIO);
        printf("error opening device %s\n", DevNameIO);
        exit(2);
    }
    ioctl(fd_1A, DIO_SET_DIRECTION, 0);
    ioctl(fd_1B, DIO_SET_DIRECTION, 0);
    ioctl(fd_1C, DIO_SET_DIRECTION, 0);
    ioctl(fd_2A, DIO_SET_DIRECTION, 0);
    ioctl(fd_2B, DIO_SET_DIRECTION, 0);
    ioctl(fd_2C, DIO_SET_DIRECTION, 0);
}
void close_io(void)
{
    close(fd_1A);
    close(fd_1B);
    close(fd_1C);
    close(fd_2A);
    close(fd_2B);
    close(fd_2C);
}
void write_io(void)
{

    BYTE buf[6];
    buf[0] = mapp->reg[0] &  0x00ff;
    buf[1] = mapp->reg[0] >> 8;
    buf[2] = mapp->reg[1] &  0x00ff;
    buf[3] = mapp->reg[1] >> 8;
    buf[4] = mapp->reg[2] & 0x00ff;
    buf[5] = mapp->reg[2] >> 8;
    write(fd_2A,&buf[0],1) ;
    write(fd_2B,&buf[1],1) ;
    write(fd_2C,&buf[2],1) ;
    write(fd_1A,&buf[3],1) ;
    write(fd_1B,&buf[4],1) ;
    write(fd_1C,&buf[5],1) ;
}


void solve(void)
{
 
        if (g_cnt==0) state(); 
        if (g_cnt==1) fileio();
        if (g_cnt==2) POWER; 
        if (g_cnt==3) PUMP; 
        if (g_cnt==4) P1A;
	if (g_cnt==5) G3D;
	if (g_cnt==6) G3B;
	if (g_cnt==7) G1B;
	if (g_cnt==8) G3H;
	if (g_cnt==9) G2F;
	if (g_cnt==10) G1F;
	if (g_cnt==11) G1F;
	if (g_cnt==12) G3G;
	if (g_cnt==13) P1A;
	if (g_cnt==14) G3E;
	if (g_cnt==15) G2E;
	if (g_cnt==16) G1E;
	if (g_cnt==17) G1D;
	if (g_cnt==18) G1D;
	if (g_cnt==19) G3D;
	if (g_cnt==20) P1A;
	if (g_cnt==21) G1D;
	if (g_cnt==22) G1D;
	if (g_cnt==23) G1B;
	if (g_cnt==24) G2B;
	if (g_cnt==25) G1B;
	if (g_cnt==26) P1A;
	if (g_cnt==27) G2B;
	if (g_cnt==28) G2B;
	if (g_cnt==29) G2A;
	if (g_cnt==30) G3D;
	if (g_cnt==31) G3D;
	if (g_cnt==32) RPUMP;
	if (g_cnt==33) RPOWER;
        if (g_cnt==34) { g_cnt=0; --cnt; i=0; }
	if (g_cnt==35) G4A; 
        if (g_cnt==36) { g_cnt=0; --cnt; i=0; }

        if (g_cnt==37) { shutdown(); }
}                         

void state()
{
	 
	if (i<AIR_NUM) { 
		if (cnt==0) { sleep(AIR_PRE); }
		if (cnt==1) qaa;
		if (cnt==2) sleep(AIR_ON); 
		if (cnt==3) cqaa;
		if (cnt==4) sleep(AIR_OFF); 
		if (cnt==5) { i++; zpp(); } // do file io and incr
	} else {
		g_cnt=35; // TEST SEQUENCE 
	}
}

void fileio()
{ 
sleep(1);
mag = seis(mag); 
	if (mag!=-1) {
		g_cnt = ((mag > 0) ? 2 : 0);
		init = 1; // initialised  
	} else { 
		g_cnt=37; // SHUTDOWN
		printf("\t>> Shutting down ...\n");
	}
--cnt;
}

int get_i(short reg,short bit)
{
    if(mapp->reg[reg] & (0x01 << bit)) return(1);
    else return(0);
}

void set_o(short reg,short bit)
{
    mapp->reg[reg] |= (0x01 << bit);
}

void clr_o(short reg,short bit)
{
    mapp->reg[reg] &= ~(0x01 << bit);
}

