/*********************************************************************************
 * BASED ON sample program from ICS ADVENT AIO16 Documentation
 * This program will prompt user for voltage between 0 and 5V
 * Output value on DAC channel 0 and read it back on ADC channel 0
 * setting scan limits (task 1)
 * performing data conversion (tak 3)
 * outputting to DAC (task 15)
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <asm/io.h>

#ifdef __GLIBC__
	#include <sys/perm.h>
#endif

#define PORT_FILE "/dev/port"

#define BASEADDRESS	0x0300 

float volts;
unsigned pntbuf[100], statcode, task;
int datbuf[100], params[5];

typedef enum {FALSE, TRUE} boolean;


/********************************* write_port_data **************************/

void write_port_data(unsigned char current[3])
{
	unsigned char value;
	int i, j;

	for (i = 0; i < 3; i++) {
		value = current[i];
		for (j = 0; j < 8; j++) {
			if (value % 2)
				putchar('1');
			else
				putchar('0');
			value = value >> 1;
		}
	}
}


/*********************************** main **************************************/

main()
{

	unsigned char b;
	unsigned char loByte, hiByte;
	static int fd = -1;
	
	/*** following output addresses are used for writing ****/
	unsigned int startADconvert = BASEADDRESS; 
	unsigned int startStopChannel = BASEADDRESS + 2;
	unsigned int FourBitDigOut = BASEADDRESS + 3;
	unsigned int DAC_0_lo = BASEADDRESS + 4;
	unsigned int DAC_0_hi = BASEADDRESS + 5;
	unsigned int DAC_1_lo = BASEADDRESS + 6;
	unsigned int DAC_1_hi = BASEADDRESS + 7;
	unsigned int cardControl = BASEADDRESS + 9;
	unsigned int counterEnable = BASEADDRESS + 10;
	unsigned int counter_0 = BASEADDRESS + 12;
	unsigned int counter_1 = BASEADDRESS + 13;
	unsigned int counter_2 = BASEADDRESS + 14;
	unsigned int counterControl = BASEADDRESS + 15;


	boolean shift_left;


	/************ initialization ****************/

	//params[0] =  BASEADDRESS;		/* starting board address */
	//params[1] = 5;			/* IRQ 5 */
	//params[2] = 1;			/* DMA channel 1 */
	//task = 0;
	// status = call_driver();		

	printf(" Base Adress is %X in hex.\n", BASEADDRESS);

	if (fd < 0)
		fd = open(PORT_FILE, O_RDWR);
	if (fd < 0) {
		printf("error opening file\n");
		exit(1);
	}



	/************ set scan limits for 0 to channel 15 *********/
	// task = 1;
	// params[0] = 0;			/* lower scan limit */
	// params[1] = 0;			/* upper scan limit */
	//status = call_driver();

	/* only one channel, channel 0 */
/*	b = 0x00;
	lseek(fd, startStopChannel, SEEK_SET);
	if (write(fd, &b, 1) > 0)
		printf("written start stop bits successfully\n"); 	
*/
	/********** DMA and IRQ ***********************************/

	/* set DMA to channel 1, channel 0 */
/*	b = 0x00;
	lseek(fd, cardControl, SEEK_SET);
	if (write(fd, &b, 1) > 0)
		printf("written card control bits successfully\n"); 	
*/

	/************* fetch a voltage ****************************/
	printf("Enter a voltage to output (0-5.0 volts): ");
	scanf("%f", &volts);
	printf("voltage: %f\n", volts);
	volts /= 5;
	volts *= 4095;
	printf("converted voltage: %f\n", volts);

	/************ set DAC 0 to output this voltage ************/

	//task = 15;
	//params[0] = 0;
	//params[1] = (int) volts;
	//status = call_driver();

//unsigned int DAC_0_lo = BASEADDRESS + 4;
//unsigned int DAC_0_hi = BASEADDRESS + 5;

	printf("value of volts in int: %d\n", (int)volts);
	printf("value of volts in Hex: %X\n", (int)volts);

	loByte = (int)volts << 4;
	hiByte = (int)volts >> 4; 
	printf("value of loByte in Hex: %X\n", loByte);
	printf("value of hiByte in Hex: %X\n", hiByte);
	
	/* channel 0, write low byte then high byte */
	lseek(fd, DAC_0_lo, SEEK_SET);
	if (write(fd, &loByte, 1) > 0)
		printf("written DAC Low byte successfully\n"); 	
	lseek(fd, DAC_0_hi, SEEK_SET);
	if (write(fd, &hiByte, 1) > 0)
		printf("written DAC high byte successfully\n"); 	


} /* end main program */


