//Project : memoryProgrammer.c
//Date    : 5/23/2005
//Author  : Curtis Rhodes with Additions from Dr. Song's SCI communication code
//Purpose : I2C Memory Chip Interface Subroutines
// Synchronous Serial Port
//	    RC3 (pin 18) == SCL (Clock for Memory Chip)
//	    RC4 (pin 23) == SDA (Serial Data for Memory Chip)
//
// Serial port
//	    RC6 (pin 25) == TX pin to send data to PC
//	    RC7 (pin 26) == RX pin to receive data from PC
//          
//Chip type   : PIC16F877A
//Clock frequency     : 20 MHz

#include <pic.h>
#include "memoryProgrammer.h"
#include "stdlib.h"
#include "stdio.h"
#if defined(_16F84) 
__CONFIG(HS & WDTDIS & PWRTEN & MPEDIS);
#endif
#if defined(_16F877) || defined(_16F877A) 
__CONFIG(HS & WDTDIS & PWRTEN & LVPDIS);
#endif
//===================================================
// main program
const char	TITLE1[] = {"Serial Communication Established."};
const char	TITLE2[] = {"Please Place Front Left EEPROMs into circuit and send file."};
const char	TITLE3[] = {"Please Place Front Right EEPROMs into circuit and send file."};
const char	TITLE4[] = {"Please Place Rear Left EEPROMs into circuit and send file."};
const char	TITLE5[] = {"Please Place Rear Right EEPROMs into circuit and send file."};
const char	MESSAGE1[] = {"Chip "};
const char	MESSAGE2[] = {" completed."};

unsigned char SCIword;
unsigned char hexValue1;
unsigned char hexValue2;
unsigned int i;
unsigned int chip_write;
unsigned int write_control;
unsigned int read_control;
unsigned char write_data;
unsigned char address_high;
unsigned char address_low;
unsigned char data;

#define WRITE_MODE 1
#define READ_MODE 2
#define WRITE_AND_READ_MODE 3

#define MODE_SELECT      WRITE_AND_READ_MODE
#define NUMBER_OF_CHIPS  8

void main(void)
{
	portInitialization();
	initializeI2C();
	rs232_initliazation(BAUD_RATE, FREQUENCY);
	display_string(TITLE1, 33);
	display_string(TITLE2, 59);
	address_high = 0x00;
	address_low = 0x00;
	chip_write = 1;
	write_control = MEMORY_CHIP0_WRITE_CONTROL;
	read_control = MEMORY_CHIP0_READ_CONTROL;
	
	if((MODE_SELECT == WRITE_MODE)|(MODE_SELECT == WRITE_AND_READ_MODE)) {
		for(i=0; i<NUMBER_OF_CHIPS; i++) {
			while(chip_write == 1) {	
				receive_byte_from_PC(&SCIword);
				if(SCIword < 0x41)
					hexValue1 = SCIword - 0x30;
				else
					hexValue1 = SCIword - 0x41 + 0x0A;
				receive_byte_from_PC(&SCIword);
				if(SCIword < 0x41)
					hexValue2 = SCIword - 0x30;
				else
					hexValue2 = SCIword - 0x41 + 0x0A;
				write_data = (hexValue1 << 4) | hexValue2;
				//PORTD = hexValue;
				memory_chip_write(write_control,address_high,address_low,write_data);
				if(address_low == 0xff) {
					if(address_high == 0xff) {
						chip_write = 0;
					}
					address_high++;
				}
				address_low++;
			}
			display_string(MESSAGE1, 5);
			display_string(MESSAGE2, 11);
			chip_write = 1;
			write_control = write_control + 2;				
		}
	}

	if((MODE_SELECT == READ_MODE)|(MODE_SELECT == WRITE_AND_READ_MODE)) {
		while(1) {
			receive_byte_from_PC(&SCIword);
			if(SCIword < 0x41)
				hexValue1 = SCIword - 0x30;
			else
				hexValue1 = SCIword - 0x41 + 0x0A;
	
			receive_byte_from_PC(&SCIword);
			if(SCIword < 0x41)
				hexValue2 = SCIword - 0x30;
			else
				hexValue2 = SCIword - 0x41 + 0x0A;
	
			address_high = (hexValue1 << 4) | hexValue2;
	
			receive_byte_from_PC(&SCIword);
			if(SCIword < 0x41)
				hexValue1 = SCIword - 0x30;
			else
				hexValue1 = SCIword - 0x41 + 0x0A;
	
			receive_byte_from_PC(&SCIword);
			if(SCIword < 0x41)
				hexValue2 = SCIword - 0x30;
			else
				hexValue2 = SCIword - 0x41 + 0x0A;
	
			address_low = (hexValue1 << 4) | hexValue2;
	
			hexValue1 = memory_chip_read(read_control,address_high,address_low);
	
			SCIword = (hexValue1 >> 4);
			if(SCIword < 0x0A)
				SCIword = SCIword + 0x30;
			else
				SCIword = SCIword - 0x0A + 0x41;
			send_byte_to_PC(SCIword);
	
			SCIword = (hexValue1 & 0b00001111);
			if(SCIword < 0x0A)
				SCIword = SCIword + 0x30;
			else
				SCIword = SCIword - 0x0A + 0x41;
			send_byte_to_PC(SCIword);
		}
	}
}

void portInitialization() {
	TRISD = 0x00; // PORTD is output
	TRISE = 0x00; // PORTD is output
	PORTD = 0xff; // Set PORTD to ensure proper initilization
	TRISC7 = 1;	// RC7 receives data from PC
	TRISC6 = 0;	// RC6 sends data to PC
}
