#include <stdio.h>
#include <unistd.h>
#include <pthread.h>    
#include <assert.h>    

#include "../hubolib.h"

using namespace HuboLib;

/*
Compile and link: 
	g++ GetAnalogInput.cpp -L../ -lhubo -lpthread -lrt -o GetAnalogInput
Run:
	sudo ./GetAnalogInput
Purpose:
	Reads the analog input as specified in the command line and returns the success of the operation.
*/

void BoostThreadPriority();

int main(int argc, char* argv[])
{
	// Lets have this program finish as soon as possible.
	BoostThreadPriority();

	if (argc != 2)
	{
		printf ("Usage: \n  GetAnalogInput <analog input to read>\n  example: GetAnalogInput 7  // this will read analog input 7 and return the result\n");
		return 0;
	}

	int channel = 0;
	if (sscanf (argv[1], "%d", &channel) != 1)
	{
		printf ("Analog input could not be determined!\n");
		return 0;
	}

	// Initialize the library once in your program.
	if (!Initialize())
	{
		printf ("Error: Initialize\n");
		return 0;
	}
	
	// Set the cycle time to 2ms (50Hz).
	Set_Cycle_Time(20);
	
	// Define channel 0 to be read (set to 1) all other channels (set to 0) are not read from the ADC.
	unsigned short overSampling[MAX_MCP3x08_CHANNELS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
	Set_MCP3x08_Oversampling (overSampling);
	
	// Wait as long until we have valid values in the buffer.
	Wait_For_MCP3x08_Buffered_Values();
	
	unsigned long 	adcCount; 
	double	 		volt;
	// Read channel 0 and output its value.
	if (Get_AI_Channel (channel, adcCount, volt))
		printf ("%ld\n", adcCount);
	else 
		printf ("-1\n");
	
	// Free library resources.
	Uninitialize();
	
	return 1;
}

void BoostThreadPriority()
{
	// Scheduling params.
	sched_param param;
	int			policy;
	int			ret;
	pthread_t	threadHandle = pthread_self();

	// Get current scheduling parameters of thread.
	ret				= pthread_getschedparam (threadHandle, &policy, &param);
	assert (ret == 0);

	// Set scheduling parameters of thread to real time values (FIFO scheduling type and max prio).
	policy				 = SCHED_FIFO; // SCHED_RR;
	param.sched_priority = sched_get_priority_max(policy); // New max priority for new scheduling concept.
	ret					 = pthread_setschedparam(threadHandle, policy, &param);
	assert (ret == 0);
}


