#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>

int main(int argc, char **argv){
	//uint16_t offsets[16] = {11, 26, 28, 28, 24, 28, 28, 22, 22, 28, 28, 28, 16, 28, 21, 28};
	//uint16_t offsets[16] = {18, 30, 17, 30, 30, 29, 30, 19, 19, 29, 25, 30, 21, 30, 30, 30};
	uint16_t offsets[16] = {-8, -13, -18, -23, -30, -26, -30, -27, -28, -30, -18, -27, -27, -30, -30, -28};

	//int16_t offsets[16] = {7, 2, -3, -8, -21, -10, -20, -11, -12, -28, -2, -11, -11, -28, -25, -12};
	//int16_t curve_offset;
	//uint16_t offsets_new[16];
	double max_vcore = 1.50;
	//double dyn_offset = -0.03125;
	double dyn_offset = -0.08125;

	//double dyn_offset = -0.075;

	double offset_high = 0.003;
	double offset_low = 0.005;

	//double new_offset = -0.08125;
	int num1, num2;
	double tmp1, tmp2, tmp3;
	//uint8_t max;
	double max_tmp;
	double avg_high = 0;
	double avg_low = 0;
	double avg_total = 0;
	double new_dyn_offset = -0.10;
	int16_t new_offsets[16];

//	new_dyn_offset = atof(argv[1]);

/*
	//for(num2=0; num2<2; num2++){
		for(num1=0; num1<16; num1++){
		//printf("%d: max: %lf high: %lf low: %lf\n", num1, max_vcore+offset_high*offsets[num1], offset_high*offsets[num1], offset_low*offsets[num1]);

		tmp1 = max_vcore + offset_high*offsets[num1] + dyn_offset;


		printf("%d: dyn_offset: %lf curve_offset: %d max: %lf high: %lf low: %lf\n", num1, dyn_offset, offsets[num1], tmp1, offset_high*offsets[num1]+dyn_offset, offset_low*offsets[num1]+dyn_offset);

		}
	printf("\n");
*/

	for(num2=0; num2<16; num2++){

		new_dyn_offset += 0.00625;
		avg_high=0;
		avg_low=0;
		avg_total=0;

		for(num1=0; num1<16; num1++){
			//new voltage must be equal or greater
			//max_vcore + offset_high*new_offsets[num1] + new_dyn_offset >= max_vcore + offset_high*offsets[num1] + dyn_offset

			if(new_dyn_offset > dyn_offset){
				tmp3 = new_dyn_offset-dyn_offset;
				new_offsets[num1] = offsets[num1] - floor(tmp3/offset_high);
			}else{
				tmp3 = dyn_offset-new_dyn_offset;
				new_offsets[num1] = offsets[num1] + ceil(tmp3/offset_high);
			}
			if(new_offsets[num1] > 30)
				new_offsets[num1] = 30;
			if(new_offsets[num1] < -30)
				new_offsets[num1] = -30;

			//new_offsets[num1] = offsets[num1] + ceil(tmp3/offset_high);
			//tmp1 = max_vcore + offset_high*offsets[num1] + dyn_offset;
			tmp1 = max_vcore + offset_high*new_offsets[num1] + new_dyn_offset;

			printf("%d: dyn_offset: %lf curve_offset: %d max: %lf high: %lf low: %lf\n", num1, new_dyn_offset, new_offsets[num1], tmp1, offset_high*new_offsets[num1]+new_dyn_offset, offset_low*new_offsets[num1]+new_dyn_offset);
			avg_high += offset_high*new_offsets[num1]+new_dyn_offset;
			avg_low += offset_low*new_offsets[num1]+new_dyn_offset;
			avg_total += offset_high*new_offsets[num1]+new_dyn_offset + offset_low*new_offsets[num1]+new_dyn_offset;
		}
		printf("dyn_offset: %lf avg_high: %lf avg_low: %lf avg_total: %lf\n", new_dyn_offset, avg_high/16, avg_low/16, avg_total/32);

	}

	return 0;
}
