

/*********************************************************************************************
*
*     Base Card: CDM-100, Revision 0
*
*     File Name: main.c
*       Project: PowerCortex
*        Module: CDM-100
*       Product: PowerCortex - M Series
*       Company: 1100 Energy Corporation
*     Author(s): Harvey Novak and Joe Petty and Bill Overholt
*
*      Version: 1.00
*      Release: 1
*         Time: 1:28 PM
*         Date: March 11, 2019
*
* Target Processor: The MSP430F249 microcontroller on the ESM C3_PM Card.
*      Description: This program manages activity within the DCM-500, communications with it's nearest neighbors,
*                   and communications with the CDM-100.  Consult the C3_PM Requirements and Design
*                   document for detailed specifications
*
*
*
*  Change History
*  ---------------
*  3/13/18    JCP   Start this project
*  3/27/18    JCP   Setup to use Low Power Mode 3
*
*
*  Soft Revisions:
*  -------------------
*  1) 05/28/19    Either pushbutton will cause P3.4 to go low, otherwise high.
*  2) 05/28/19    Commented out the SPI initialization, causes issues on at least one card.
*  3)
*  4)
*  5)
*  6)
*  7)
*     
*     
*
*  Key Words:
*     VBB_OUT    BATTERY_BUS    nI_Sns_PWR    P3OUT   Setup_SPI1_UART1
*********************************************************************************************/

#include <msp430.h>
#include "Definitions.h"
#include <stdio.h>
#include <string.h>
#include "TI_USCI_I2C_master.h"
#include "Screens.h"

// Values that are changed during interrupt handling

// Global variables
// Active screen on display:
//  1 - Main
//  2 - I/O Status
//  3 - Temperature
//  4 - Battery Ststus
//  7 - Output Settings
//  8 - Diagnostics
//  9 - About
// Module group 0 (0-5), 6 (6-11), 12(12-15)
UI_8    Module_Index;                   // Starting Index for module group

UI_8    Module_Tx[8] = {0xFF,0x00,0x11,0x22,0x44,0x88,0x7E, 0xFF};
// Data structure for all modules
MODULE_STRUCT Module[15];             // Data on each Module

//Video Display Page Offsets
#define PAGE_  (0x00)
#define PAGE_0	(0x04)

//FPGA Register Addresses
#define REV_CODE					(0x00)
#define PLD_STATUS				(0x01)
#define BL_SHDNN					(0x02)
#define AR_LOAD_PAGE			(0x03)
#define AR_GRID_ROW				(0x04)
#define AR_GRID_POS				(0x05)
#define AR_DMA_SIZE				(0x06)
#define AR_ASCII_HEX			(0x07)
#define AR_WRITE					(0x08)
#define AR_DONE					  (0x09)
#define AR_ACTIVE_PAGE		(0x0A)
#define DISP_BRT					(0x0B)
#define DISP_BANNER_SIZE	(0x0C)
#define VR_DISP_PAGE      (0x0D)
#define AR_ASCII_READ      (0x0E)

#define Touch_Screen   (0x4A) //Touch Screen I2C address
#define SMCLK_2M       (0x06) // Set SMCLK to 2Mhz, assumes DCOCLK at 16Mhz
#define I2C_PRESCALE   (0x14) // Div SMCLK to get bit rate
//----------------------------------------------------------------------------
// External routines
//----------------------------------------------------------------------------

extern void Setup_Clocks(void);
//extern void Setup_Vars(void);
extern void Setup_SPI1_UART1(void);
extern void Setup_ADC12(void);

//----------------------------------------------------------------------------
// Functions
//----------------------------------------------------------------------------

void delay(int cnt)
{
    while (cnt > 0) {
       cnt = cnt - 1;
    }
}

int Read_fpga(int address)
{
int input_reg;

   P1DIR = 0xFF; 			//set port 1 to output
   P1OUT = address; 	//set read address on port 1
   P4OUT |=  PIN2; 		//set cpu_rdn high, port4.2
//   P4OUT &= ~PIN0; 		//set pld_cen low, port 4.0
   delay(10);
   P4OUT |=  PIN1; 		//strobe cpu_ale, port 4.1
   delay(10);
   P4OUT &= ~PIN1;
   P1DIR = 0x00; 			//set port 1 to input
   delay(10);
   P4OUT &= ~PIN2;		//set cpu_rdn low
   delay(10);
   input_reg = P1IN;   //latch data on port 1
//   P4OUT |=  PIN0;      //set pld_cen high
   P4OUT |=  PIN2; 		//set cpu_rdn high
   return input_reg;	//return input_reg
}

void Write_fpga(int address, int data)
{
   P1DIR = 0xFF; 			//set port 1 to output
   P1OUT = address; 	//set write address on port 1
   P4OUT |=  PIN2; 		//set cpu_rdn high, port4.2
//   P4OUT &= ~PIN0; 		//set pld_cen low, port 4.0
   delay(10);
   P4OUT |=  PIN1; 		//strobe cpu_ale, port 4.1
   delay(10);
   P4OUT &= ~PIN1;
   delay(10);
   P1OUT = data; 	//set write data on port 1
   P4OUT &= ~PIN0;        //strobe pld_cen low, port 4.0
   delay(10);
   P4OUT |=  PIN0; 		//set pld_cen high   
   P1DIR = 0x00; 			//set port 1 to input
}

void Write_dpram(int page, int row, int pos, int ascii)
{
		Write_fpga(AR_LOAD_PAGE, page); //
		Write_fpga(AR_GRID_ROW, row); //
		Write_fpga(AR_GRID_POS, pos); //
		Write_fpga(AR_ASCII_HEX, ascii); //

		Write_fpga(AR_WRITE, 0X1); // strobe the write enable
		Write_fpga(AR_WRITE, 0X0); // 

}

int Read_dpram(int page, int row, int pos)
{
		int out;
		
		Write_fpga(AR_LOAD_PAGE, page); //
		Write_fpga(AR_GRID_ROW, row); //
		Write_fpga(AR_GRID_POS, pos); //
		
		out = Read_fpga(AR_ASCII_READ);
		return out;

}


void Write_top_banner()
{
	int r;
	int p;
	int row_data;
	
//Line 1
	Write_dpram(0x0, 0x01, 0x02, 0x14);
	Write_dpram(0x0, 0x01, 0x07, 0x15);

//Line 2
	Write_dpram(0x0, 0x02, 0x01, 0x10);
	Write_dpram(0x0, 0x02, 0x02, 0x17);
	Write_dpram(0x0, 0x02, 0x03, 0x17);
	Write_dpram(0x0, 0x02, 0x06, 0x17);
	Write_dpram(0x0, 0x02, 0x07, 0x17);
	Write_dpram(0x0, 0x02, 0x08, 0x11);
	Write_dpram(0x0, 0x02, 0x23, 0x31);
	Write_dpram(0x0, 0x02, 0x24, 0x30);
	Write_dpram(0x0, 0x02, 0x25, 0x30);
	Write_dpram(0x0, 0x02, 0x26, 0x25);

//Line 3
	Write_dpram(0x0, 0x03, 0x02, 0x15);
	Write_dpram(0x0, 0x03, 0x07, 0x14);


		for(r=0; r<=4; r++) //set all banner grids to highlight
		{	
			for(p=0; p<=39; p++)
			{
			    row_data = Read_dpram(0x0, r, p);
			    row_data = row_data |= 0x80;
			    Write_dpram(0x0, r, p, row_data);
			}
		}

}

void Write_bottom_banner()
{
	int r;
//	int p;
//	int row_data;

// High Lights
	for(r=0x13; r<=0x16; r++) //
	{	
		Write_dpram(0x0, r, 0x01, 0x80);
		Write_dpram(0x0, r, 0x02, 0x80);
		Write_dpram(0x0, r, 0x03, 0x80);
		Write_dpram(0x0, r, 0x04, 0x80);
		Write_dpram(0x0, r, 0x05, 0x80);
		Write_dpram(0x0, r, 0x06, 0x80);
		Write_dpram(0x0, r, 0x09, 0x80);
		Write_dpram(0x0, r, 0x0A, 0x80);
		Write_dpram(0x0, r, 0x0B, 0x80);
		Write_dpram(0x0, r, 0x0C, 0x80);
		Write_dpram(0x0, r, 0x0D, 0x80);
		Write_dpram(0x0, r, 0x0E, 0x80);
	}

	for(r=0x14; r<=0x16; r++) //
	{	
		Write_dpram(0x0, r, 0x11, 0x80);
		Write_dpram(0x0, r, 0x12, 0x80);
		Write_dpram(0x0, r, 0x13, 0x80);
		Write_dpram(0x0, r, 0x14, 0x80);
		Write_dpram(0x0, r, 0x15, 0x80);
		Write_dpram(0x0, r, 0x16, 0x80);
		Write_dpram(0x0, r, 0x17, 0x80);

		Write_dpram(0x0, r, 0x1A, 0x80);
		Write_dpram(0x0, r, 0x1B, 0x80);
		Write_dpram(0x0, r, 0x1C, 0x80);
		Write_dpram(0x0, r, 0x1D, 0x80);
		Write_dpram(0x0, r, 0x1E, 0x80);
		Write_dpram(0x0, r, 0x1F, 0x80);
	}
	
//Line 14
	Write_dpram(0x0, 0x14, 0x03, 0x94);
	Write_dpram(0x0, 0x14, 0x04, 0x95);

	Write_dpram(0x0, 0x14, 0x0A, 0x95);
	Write_dpram(0x0, 0x14, 0x0D, 0x94);

//Line 15
	Write_dpram(0x0, 0x15, 0x02, 0x94);
	Write_dpram(0x0, 0x15, 0x05, 0x95);

	Write_dpram(0x0, 0x15, 0x0B, 0x95);
	Write_dpram(0x0, 0x15, 0x0C, 0x94);                         
                            
	Write_dpram(0x0, 0x15, 0x12, 0xC5);//E
	Write_dpram(0x0, 0x15, 0x13, 0xCE);//N
	Write_dpram(0x0, 0x15, 0x14, 0xD4);//T
	Write_dpram(0x0, 0x15, 0x15, 0xC5);//E
	Write_dpram(0x0, 0x15, 0x16, 0xD2);//R
	Write_dpram(0x0, 0x15, 0x1B, 0xCD);//M
	Write_dpram(0x0, 0x15, 0x1C, 0xC5);//E
	Write_dpram(0x0, 0x15, 0x1D, 0xCE);//N
	Write_dpram(0x0, 0x15, 0x1E, 0xD5);//U
}

//----------------------------------------------------------------------------
//
//  Function: main
//
//  Description: Start point for CDM-100 Main Controller
//
//  Pre-Conditions: None
//
//  Parameters
//    Input: None
//    Output: None
//
//----------------------------------------------------------------------------


void main(void)
{
    unsigned int in_data;
//    unsigned int ascii_data;
    unsigned int i;

    unsigned int active_screen;

  UI_16  MSec_Count = 0;
  UI_16  USec_Count = 0;
  UI_16  Sec_Count = 2;

  char Display_line_02[40];
  char Display_line_07[40];
  char Display_line_09[40];
  char Display_line_0B[40];
  char Display_line_0D[40];
  char Display_line_0F[40];
  char Display_line_11[40];


  WDTCTL = WDTPW + WDTHOLD;		// Stop WDT

  //Set_Clock for 16 MHz from external crystal and DCO
//  Setup_Clocks();
    DCOCTL = 0;                   // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_16MHZ;       // Set range
    DCOCTL = CALDCO_16MHZ;        // Set DCO step + modulation */
    BCSCTL2 = SMCLK_2M;           //
    BCSCTL3 = LFXT1S_2;           // VLO for ACLK (~12Khz)
  
  //Setup all global variables
//  Setup_Vars();


  // Port pin assignments

  // Setup Port 1: DIN0-7
  P1SEL = 0;			// All GPIO
  P1DIR = 0;			// All pins to input

  // Setup Port 2: Interrupts for Status and Keypad 
  P2SEL = 0;			// All GPIO
  P2DIR = 0;			// All Inputs
  P2REN = PORT2_REN;	// Enable resistors on keypad pins
  P2OUT = PORT2_OUT;	// Set resistors to pull-up
  P2IE = PORT2_IE;		// Allow interrupts
  P2IES = PORT2_IES;	// Select interrupt edge
  P2IFG = 0;    		// Clear the interrupt flags

  // Setup Port 3: 
  P3SEL = PORT3_SEL;    //
  P3DIR = PORT3_DIR;    //
  P3OUT = IM_RESETn;    // P3.5 high by default,

  // Setup Port 4:
  P4SEL = 0;
  P4DIR = ( PIN0 | PIN1 | PIN2 );

  // Setup Port 5:
  P5SEL = 0;
  P5DIR = 0xF0;
//  P5OUT = ( PIN7 | PIN6 );
  P5OUT = ( PIN6 | PIN5 | PIN4 );
  P5OUT &= ~PIN7;  //turn off P5.7 , turns on display power
//  P5OUT |=  PIN7;  //turn on P5.7 , turns off display power

  // Setup Port 6:
  P6SEL = 0;
  P6DIR = 0;

  // Setup Timer_A3
  TACTL = TACLR;                       // Halt and clear the timer
  TACCR0 = TACCR1 = TACCR2 = 0;        // Halt all counters
  TACTL = TASSEL_2 + ID_0 + MC_1;      // AMCLK, /8, Count Up, start the counter
  TACCR0 = 7950;                       // Start the counter




  // Configure SPI and UART
  Setup_SPI1_UART1();

  // Configure the ADC on Port 6
  Setup_ADC12();

  __enable_interrupt();                // Enable interrupts

  // Configure the watchdog timer
  WDTCTL = WDTPW + WDTHOLD;		// Stop WDT
  // -- Password, Clear Count, SMCLK
  // -- Period = 32768 @ 16 MHz = 2.0 milliseconds
  // -- Start Watchdog with the default mode
//  WDTCTL = WDTPW + WDTCNTCL;

  // Select the special function to output MCLK, SMCLK and ACLK on P5.4/5/6  --- JCP
//  P5SEL = PIN4 + PIN5 + PIN6;
  // Turn off the LED
  P1OUT = 0;
  while(Read_fpga(REV_CODE) != 0x04); //wait for fpga to boot

	Write_fpga(DISP_BRT, 0x09); // SET DISPLAY BRIGHTNESS
	Write_fpga(DISP_BANNER_SIZE, 0x00); // SET BANNER SIZE, LEAVE THIS SET TO 0x0
	Write_fpga(VR_DISP_PAGE, PAGE_); // SET DEFAULT DISPLAY PAGE
    Write_fpga(AR_ACTIVE_PAGE, 0X0); // SET ACTIVE RAM, LEAVE THIS SET TO 0x0
    Write_fpga(BL_SHDNN, 0x01); // TURN ON DISPLAY
//    Write_fpga(BL_SHDNN, 0x00); // TURN OFF DISPLAY



    Write_top_banner();
    Write_bottom_banner();

//fprintf(stderr, "Hello\n");

//*****************************************************************
// Touch Screen testing
    while(1) //Loop here for testing only
    {

UI_8 read_adr[2];
UI_8 read_data[16];
UI_8 read_bytes;
UI_8 xmit_bytes;


//read address = 0x0000 start of ID Info Table
read_adr[0] = 0x03; //put LSB here
read_adr[1] = 0x00;
read_bytes = 0x08;
xmit_bytes = 0x02;

//Init I2C for Touch Screen xmit
            P3OUT &= ~PIN4;  // TURN ON P3.4 led

			TI_USCI_I2C_transmitinit(Touch_Screen, I2C_PRESCALE);
			_EINT();

			TI_USCI_I2C_transmit(xmit_bytes, read_adr);

			P3OUT |= PIN4;  // TURN OFF P3.4 led

//Init I2C for Touch Screen receive
//            P3OUT &= ~PIN4;  // TURN ON P3.4 led

			TI_USCI_I2C_receiveinit(Touch_Screen, I2C_PRESCALE);
			_EINT();

			TI_USCI_I2C_receive(read_bytes, read_data);

//            P3OUT |= PIN4;  // TURN OFF P3.4 led

			fprintf(stderr, "Data returned\n");
			fprintf(stderr, "%x\n", read_data[0]);
			fprintf(stderr, "%x\n", read_data[1]);
			fprintf(stderr, "%x\n", read_data[2]);
			fprintf(stderr, "%x\n", read_data[3]);
			fprintf(stderr, "%x\n", read_data[4]);
			fprintf(stderr, "%x\n", read_data[5]);
            fprintf(stderr, "%x\n", read_data[6]);
            fprintf(stderr, "%x\n", read_data[7]);


	active_screen = 0x00; 
			

    if(TACCTL0 && CCIFG)
    {     
      TACTL |= TACLR;
      TACCTL0 = 0;
      USec_Count++;
    }

    if (USec_Count > 2) // was 1000
    {
      USec_Count = 0;
      MSec_Count++;
    }

    if (MSec_Count > 80)  //was 700
    {     
      MSec_Count = 0;
      Sec_Count++;

//      in_data = Read_fpga(REV_CODE);
//      if (in_data == 0x04)
//      {
//              P3OUT ^= PIN4;  // Toggle P3.4 led
              
//              if (active_screen == 0x40) //Toggle screen for testing
//              	{
//              		active_screen = 0x00;
//              	}
//              else
//              	{
//              		active_screen = 0x40;
//              	}
//      }


  }

  //  --------------   End operational spin loop  ----------------

} // End CDM-100 main

