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

#include "../hubolib.h"
#include "../hubocfg.h" // Required for changing default I2C device.

using namespace HuboLib;

/*
Compile and link: 
	g++ SetCycleTime.cpp -L../ -lhubo -lpthread -lrt -o SetCycleTime.out
Run:
	sudo ./SetCycleTime.out
Purpose:
	The cycle time specifies how fast the IO chips are polled/set by the background thread.
	It therefore determines the frequency of which the internal buffers are updated. 
	As we've learned from the oversampling-demos there is of cause the natural 
	limitation given to the frequency you can request. This limit is depending on the CPU 
	speed the scheduler of the OS and other threads running at highest priority and of cause
	by the number of analog channels to be oversampled (including their oversampling count).
	
	The fastest polling that could reasonable be achieved (without breaking the cycle time)
	worked out to be 2ms (hence 500Hz) when latching 1 analog channel only. The absolute
	maximum is 1ms referring to 1000Hz.
	The default setting for the cycle time is 10ms (100Hz).
*/

int main(void)
{
	// If required - set the I2C device to work with. The Raspberry Pi uses "/dev/i2c-1" which is default, the Banana Pi uses "/dev/i2c-0"
	#ifdef BPI
	    g_I2CConfig.m_sI2CDevice = "/dev/i2c-0";
	#endif

	// Initialize the library once in your program.
	if (!Initialize())
	{
		printf ("Error: Initialize\n");
		return 1;
	}

	// Let's use the default cycle time first.
	
	printf ("Lower input 2 in order to switch to a higher cycle time of 1s.\n");

	unsigned char allInputs = 0;
	while (1) 
	{
		// It doesn't matter how fast the main thread is polling.
		// It would only access the buffers (but not directly the hardware) anyway!
		Get_DI_Channels(allInputs);
		printf ("Digital inputs (hex) = 0x%02X\n", allInputs);

		usleep(10000);
		
		// Break if input 2 is lowered.
		if (~allInputs & 4)
			break;
	} 
	// Result: You'll see an almost immediate change of the input once triggered. This is why the 
	// buffer gets updated 100 times a second.
	

	// Lower the cycle time to 1s.
	Set_Cycle_Time(1000);

	printf ("Lower input 1 in order to switch to a higher cycle time of 1s.\n");

	while (1) 
	{
		Get_DI_Channels(allInputs);
		printf ("Digital inputs (hex) = 0x%02X\n", allInputs);

		usleep(10000);
		
		// Break if input 1 is lowered.
		if (~allInputs & 2)
			break;
	} 
	// Result: Here the buffer only gets updated once a second. Hence access to it will return 
	// a former latched value. Also - if switching the inputs inbetween a cycle - you might not 
	// recognize an input change as polling is to slow for fast signals. 

	// Free library resources.
	Uninitialize();
	
	return 0;
}
