/*
 * oled.c
 * by Mauro Grassi May 2007, April 2009.
 * Driver for 4D Systems uOLED-96-G1 OLED module
 *
 * Connected by serial interface through UART port
 *   
*/

#include "h/oled.h"
#include "h/uart.h"

unsigned int colour_oled;      	// currently selected colour
char x_oled;                    // current x position
char y_oled;                    // current y position

#if(USE_OLED)

void initOLED(void)
{	
	LATBbits.LATB5=0;
	initUART();
	delayMs(500);
	LATBbits.LATB5=1;			// oled reset
	delayMs(600);
	sendUART(0x55);
	clsOLED();
}

void setBackgroundColourOLED(unsigned int colour)
{
	sendUART(0x42);
	sendUART(colour>>8);
	sendUART(colour);
}

void setColourOLED(unsigned int colour)
{
	colour_oled=colour;
}

void advanceCursorOLED(void)
{
	x_oled++;
	if(x_oled>XLIMIT)
	{
	x_oled=0; y_oled++;
	}
	if(y_oled>YLIMIT)
	{ 
	y_oled=0; x_oled=0;
	}
	if(x_oled<0)x_oled=0;
	if(y_oled<0)y_oled=0;
}

void clsOLED(void)
{
  	x_oled=0;
  	y_oled=0;
	colour_oled=0xFFFF;
	sendUART(0x45);        // erase screen
	sendUART(0x4F);
	sendUART(0x01);			// opaque text
	delayMs(10);
}

void setFontSizeOLED(BYTE x)
{
	// x= 0, 1, 2
	sendUART(0x46);
	sendUART(x);
}

void writecOLED(BYTE x)
{
	sendUART(0x4F);
	sendUART(0x01);				// opaque text
	sendUART(0x54);
	sendUART(x);
	sendUART(x_oled);
	sendUART(y_oled);
	sendUART(colour_oled>>8);
	sendUART(colour_oled);
	advanceCursorOLED();
}

void setCursorOLED(char x, char y)
{
	x_oled=x-1;
	y_oled=y;
	advanceCursorOLED();
}

void writeStringOLED(char* string)
{
	while((*string)!=0)
	{
		writecOLED(*string);
		string++;
	}
}

void writeStringPaddedOLED(char* string, int padding)
{
	int i;
	i=0;
	while((*string)!=0)
	{
		writecOLED(*string);
		string++;
		i++;
	}
	while(i<padding)
	{
	writecOLED(' ');
	i++;
	}
}

void writeStringAtOLED(char x, char y, char* string)
{
	setCursorOLED(x, y);
	writeStringOLED(string);
}

void writeStringAtPaddedOLED(char x, char y, char* string, int padding)
{
	setCursorOLED(x, y);
	writeStringPaddedOLED(string, padding);
}

void killOLED()
{
	sendUART(0x45);
	sendUART(0x59);
	sendUART(0x01);
	sendUART(0x00);
	sendUART(0x59);
	sendUART(0x03);
	sendUART(0x00);
}

#endif

BYTE disFix(BYTE x)
{
	x&=0x0F;
	if(x<=9)return x+'0'; else return x+7+'0';
}

#if (USE_OLED)
void disafreeOLED(BYTE z)
{
	writecOLED(disFix(z>>4));
	writecOLED(disFix(z));
}

void disaOLED(char x, char y, BYTE z)
{
	setCursorOLED(x, y);
	disafreeOLED(z);
}

void diswordfreeOLED(unsigned int num)
{
	disafreeOLED(num>>8);
	disafreeOLED(num);
}

void disdwordfreeOLED(unsigned long num)
{
disafreeOLED(num>>24);
disafreeOLED(num>>16);
disafreeOLED(num>>8);
disafreeOLED(num);
}
#endif

int iitoa(int num, char *mystr, int radix, int blanking)
{
    int i,a;
    unsigned int n,l;
	char buffer[8];
	a=0;
	n=num;
	for(i=0;i<8;i++){

         l=0xF&(n%radix);
         n=n/radix;

         if(l>9)l+=7;
	 l+=0x30;
	 buffer[a]=l; 
	 a++;
	 }	
	a=0;
	for(i=7;i>-1;i--){
		if((blanking!=1)){ mystr[a]=buffer[i]; a++; }
		if((blanking==1)&&(buffer[i]!=0x30)){ blanking=0; mystr[a]=buffer[i]; a++; }
		if((blanking==1)&&(buffer[i]==0x30)&&(i==0)){ mystr[a]=0x30; a++; }
		}
	mystr[a]=0x00;
	a++;
	return a;
}

#if(USE_OLED)
void disdecfreeOLED(int num, int digits)
{
	int i;
	char mystring[20];
	i=iitoa(num,mystring,10, 0);
	writeStringOLED(&mystring[i-digits-1]);
}

void disdecOLED(char x, char y, int num)
{
	setCursorOLED(x, y);
	disdecfreeOLED(num, 2);
}

void disFUnsignedOLED(char x, char y, double f, int numdec, int mode, int padding)
{
	int i;
	char buffer[NUM_DIGITS+3];

	if(f<0.0)f=-f;
	i=printFDecimal((unsigned char*)buffer, f, numdec, mode);
	writeStringAtPaddedOLED(x, y, &buffer[i], padding);
}
#endif
