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

/*
#define RANKS 4
#define VDD 1.42
#define PROCODT 60

struct rank_attr{
	double drive_strength;
	double rtt_nom;
	double rtt_wr;
	double rtt_park;
};
*/

/*
write to cs0
read from cs 0

4 reads
4 writes
no active cs


struct Odt_State {
	bool rtt_nom;
	bool rtt_wr;
	bool rtt_park;
};
*/

#define RTT_PARK 0
#define RTT_WR 1
#define RTT_NOM 2
#define RTT_OFF 3



const char Odt_State[5][2] = {
	//no active cs
	{RTT_PARK, RTT_PARK},
	//writes
	{RTT_WR, RTT_NOM},
	{RTT_PARK, RTT_WR},
	//reads
	{RTT_OFF, RTT_NOM},
	{RTT_PARK, RTT_OFF}
};




int main(int argc, char **argv){
	//struct rank_attr Ranks[RANKS];
	const int ranks = 2;
	const int max_odt_states = 5;
	const double voltage = 1.5;
	const double procodt = 32;
	const double dram_drive = 40;
	const double proc_drive = 34;
	const double rtt_nom = 40;
	const double rtt_wr = 80;
	const double rtt_park = 40;
	const double rtt_off = 0;
	const double estimated_line_z = 40;
	double tmp1 = 0;
	double tmp2 = 0;
	double tmp3 = 0;
	double zero = 0;
	int cs = 0;
	int state = 0;
	double Cur_Termination = 0;
	double Total_Resistance = 0;
	const char *description[5] = {"No active cs", "Write to cs1", "Write to cs0", "Read from cs1", "Read from cs0"};

//∞
//	struct Odt_State odt_state[];


	printf("dram drive strength(Read): %.02lfohms\n", dram_drive);
	printf("proc drive strength(Write): %.02lfohms (est. not user selectable)\n", proc_drive);

	printf("dram drive current(Read): %.04lfamps\n", voltage/dram_drive);
	printf("proc drive current(Write): %.04lfamps (est. not user selectable)\n", voltage/proc_drive);

	printf("ProctODT\tCS3\tCS2\tCS1\tCS0\tI to VDDQ\tOhms\tDescription\n");
	for(state = 0; state<max_odt_states; state++){
		Total_Resistance = 1/procodt;
		printf("%.02lf\t\t", procodt);
		for(cs = 0; cs<ranks; cs++){
			if(Odt_State[state][cs] == RTT_PARK){
				Cur_Termination = rtt_park;
			}else if(Odt_State[state][cs] == RTT_WR){
				Cur_Termination = rtt_wr;
			}else if(Odt_State[state][cs] == RTT_NOM){
				Cur_Termination = rtt_nom;
			}else{
				Cur_Termination = rtt_off;
			}
			if(Cur_Termination == zero){
				printf("∞\t");
			}else{
				printf("%.02lf\t", Cur_Termination);
			}
			if(Cur_Termination != zero){
				tmp1 = 1;
				tmp1 /= Cur_Termination;
				Total_Resistance += tmp1;
			}
		}
		tmp1 = 1;
		tmp1 /= Total_Resistance;
		printf("%.04lf\t", voltage/tmp1);
		printf("\t%.04lf\t", tmp1);
		printf("\t%s\n", description[state]);

	}


	//calculate estimated drive current at dram reciever to each rank
	//write

/*
	//drive current at source
	tmp1 = voltage/proc_drive;
	//current loss to destination
	tmp2 = voltage/estimated_line_z;
	tmp3 = tmp1 - tmp2;

	printf("write to dram:\n");
	printf("\tdrive current at source: %lfA\n", tmp1);
	printf("\tmax current at destination: %lfA\n", tmp3);

	//read

	tmp1 = voltage/dram_drive;
	tmp2 = voltage/estimated_line_z;
	//tmp3 = tmp2 - voltage/procodt;
	tmp3 = tmp1 - tmp2;

	printf("read from dram:\n");
	printf("\tdrive current at source: %lfA\n", tmp1);
	printf("\tmax current at destination: %lfA\n", tmp3);
*/

	//calculate estamated drive current at proc reciever from each rank
	//write
	//read

	return 0;
}
