#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "config_pad_mode.h"
//#include "cspi_defines.h"
//#include "cspi_functions.h"


U32 IntFlag;

U32 Base_Addr0 = 0x43FA4000;
U32 Base_Addr3 = 0x53F84000;
U32 Base_Addr1 = 0x50010000;

#define REG_CSPI3_CONREG (*(volatile long*) CSPI3_CONREG)

#define NIVECSR 0x68000040

#define DISABLE_CSPI_IRQS mem32_write(AVIC_INTDISNUM, 14)

#define ENABLE_CSPI_IRQS mem32_write(AVIC_INTENNUM, 14)


U32 TIMEOUT=1000;

//enable and disable interrupts to the ARM core function definitions

__inline void enable_IRQ(void)
{
    int tmp;
    __asm
    {
        MRS tmp, CPSR
        BIC tmp, tmp, #0x80
        MSR CPSR_c, tmp
    }
}

__inline void disable_IRQ(void)
{
    int tmp;
    __asm
    {
        MRS tmp, CPSR
        ORR tmp, tmp, #0x80
        MSR CPSR_c, tmp
    }
}

__inline void enable_FIQ(void)
{
    int tmp;
    __asm
    {
        MRS tmp, CPSR
        BIC tmp, tmp, #0x40
        MSR CPSR_c, tmp
    }
}

__inline void disable_FIQ(void)
{
    int tmp;
    __asm
    {
        MRS tmp, CPSR
        ORR tmp, tmp, #0x40
        MSR CPSR_c, tmp
    }
}





void test(void)
{

	int k ;

// minimal connections :
// SPI3 CLK (pin 3 of J15) should be tied to SPI1 CLK (J17, pin C4)
// SPI1 SS (pin 5 of J15) should be grounded 
// SPI3 MISO (pin 8 of J15) should be tied to SPI1 MISO (pin C3 of J17)

	enable_IRQ() ; 
	
// pause just for test if our exceptions will occur

	for ( k = 0; k < 10 ; k++ ) printf ("*") ;
			
	mem32_write (CSPI3_TXDATA, 0x00000123);	
  	
  	printf("\n") ;
  	
  	REG_CSPI3_CONREG |= 4 ;	// start
	
	while (REG_CSPI3_CONREG & 4) ;

	printf ("CSPI1_Stat %x\n", mem32_read (CSPI1_STATREG)) ; 	
	printf ("CSPI3_Stat %x\n", mem32_read (CSPI3_STATREG)) ; 	

	printf ("NIVECSR %x\n", mem32_read (NIVECSR)) ; 	


//	printf ("CSPI1_intreg %x\n", mem32_read (CSPI1_INTREG)) ; 	
//	printf ("CSPI1_Data %x\n", mem32_read (CSPI1_RXDATA)) ; 	


}


void CSPI_Init(void)
{

// int k ;
 
// disable 
 
  	mem32_write (CSPI3_CONREG, 0);	
 	mem32_write (CSPI1_CONREG, 0);	


	// configure CSPI IOs
	
	set_iomux_cspi1_via_dedicated_pins (); 
	set_iomux_cspi3_via_dedicated_pins ();
//	set_iomux_cspi2_via_dedicated_pins ();
// 	mem32_write (Base_Addr1 + 0x08, 0x0);	//CSPI2 Master

  	mem32_write (CSPI3_CONREG, 0x00071f03);	//CSPI3 Master, 32-bit
 	mem32_write (CSPI1_CONREG, 0x00071f01);	//CSPI1 Slave

//  enable CSPI interrupts

	mem32_write (CSPI3_INTREG, 0x00000000);		// mask Master interrupts
	mem32_write (CSPI1_INTREG, 0x00000008);		// enable Slave interrupts
//	mem32_write (CSPI1_INTREG, 0x00000100);		// enable Slave TC interrupts

//	mem32_write (CSPI1_INTREG, 0x00000000);		// mask Slave interrupts for test


	ENABLE_CSPI_IRQS ;
}



void wait(int time_out)
{
	int i;

	for (i = 0;i < time_out;i++);	
}


void test_exit(int err)
{
	if (err)
	  	printf("TEST FAILED!\n");
	else
	  	printf("TEST PASSED!\n");
	
	printf ("END_TEST\n");
	exit (err);
}


void iomux_config(void) 
{
  config_pad_mode(LD0,func_out,func_in); 
  config_pad_mode(LD1,func_out,func_in); 
  config_pad_mode(LD2,func_out,func_in); 
  config_pad_mode(LD3,func_out,func_in); 
  config_pad_mode(LD4,func_out,func_in); 
  config_pad_mode(LD5,func_out,func_in); 
  config_pad_mode(LD6,func_out,func_in); 
  config_pad_mode(LD7,func_out,func_in); 
  config_pad_mode(LD8,func_out,func_in); 
  config_pad_mode(LD9,func_out,func_in); 
  config_pad_mode(LD10,func_out,func_in); 
  config_pad_mode(LD11,func_out,func_in); 
  config_pad_mode(LD12,func_out,func_in); 
  config_pad_mode(LD13,func_out,func_in); 
  config_pad_mode(LD14,func_out,func_in); 
  config_pad_mode(LD15,func_out,func_in); 
  config_pad_mode(LD16,func_out,func_in); 
  config_pad_mode(LD17,func_out,func_in); 
  config_pad_mode(ATA_CS0,alt2_out,alt2_in); 
  config_pad_mode(ATA_CS1,alt2_out,alt2_in); 
  config_pad_mode(ATA_DIOR,alt2_out,alt2_in); 
  config_pad_mode(ATA_DIOW,alt2_out,alt2_in); 
//  config_pad_mode( CSI_D4,func_out,func_in); 
//  config_pad_mode( CSI_D5,func_out,func_in); 
  config_pad_mode( CSI_D6,func_out,func_in); 
  config_pad_mode( CSI_D7,func_out,func_in); 
  config_pad_mode( CSI_D8,func_out,func_in); 
  config_pad_mode( CSI_D9,func_out,func_in); 
  config_pad_mode(CSI_D10,func_out,func_in); 
  config_pad_mode(CSI_D11,func_out,func_in); 
  config_pad_mode(CSI_D12,func_out,func_in); 
  config_pad_mode(CSI_D13,func_out,func_in); 
  config_pad_mode(CSI_D14,func_out,func_in); 
  config_pad_mode(CSI_D15,func_out,func_in); 
  config_pad_mode(VSYNC0,func_out,func_in); 
  config_pad_mode(SRST0,alt2_out,alt2_in); 
  config_pad_mode(SD_D_IO,func_out,func_in); 
  config_pad_mode(CSI_HSYNC,alt2_out,func_in); 
  config_pad_mode(CSI_PIXCLK,alt2_out,func_in); 
  config_pad_mode(CSI_VSYNC,alt2_out,func_in);
  config_pad_mode(CONTRAST,func_out,func_in); 
  config_pad_mode(LCS0,func_out,func_in); 
  config_pad_mode(VSYNC0,func_out,func_in); 
  config_pad_mode(LCS1,func_out,func_in); 
  config_pad_mode(SCLK0,alt2_out,alt2_in); 
  config_pad_mode(FPSHIFT,func_out,func_in); 
  config_pad_mode(D3_CLS,func_out,func_in); 
  config_pad_mode(DRDY0,func_out,func_in); 
  config_pad_mode(HSYNC,func_out,func_in); 
  config_pad_mode(D3_REV,func_out,func_in); 
  config_pad_mode(D3_SPL,func_out,func_in); 
  config_pad_mode(VSYNC3,func_out,func_in); 
  config_pad_mode(PAR_RS,func_out,func_in); 
  config_pad_mode(READ,func_out,func_in); 
  config_pad_mode(SD_D_CLK,func_out,func_in); 
  config_pad_mode(SER_RS,func_out,func_in); 
  config_pad_mode(WRITE,func_out,func_in); 
  config_pad_mode(CSI_MCLK,func_out,func_in); 
  config_pad_mode(CSPI2_SS2,alt2_out,alt2_in); 
}





void cspi1_int_routine(void) 
{

  IntFlag = mem32_read (CSPI1_INTREG) & mem32_read (CSPI1_STATREG);

  mem32_write (CSPI1_INTREG, 0x00000000); 
}


void cspi2_int_routine(void) 
{

  IntFlag = mem32_read (CSPI2_INTREG) & mem32_read (CSPI2_STATREG);

  mem32_write (CSPI2_INTREG, 0x00000000);
}


WORD cspi_polling (WORD reg_addr, WORD exp_val) 
{

  WORD i;
  WORD act_val;
  WORD poll_check; 

  poll_check = 0;
  for (i = 0; i < TIMEOUT; i++)
  {
    act_val = mem32_read (reg_addr);
    if (act_val == exp_val)
    {
       poll_check = 1;
       break;
       }
   }
 
   if (poll_check == 0) {
  	//verilog_trigger(arm_vt_fail);
	printf("\ncspi_polling fail @ register addr 0x%X", reg_addr);
       printf("\nExpected value = 0x%X,   Actual value = 0x%X", exp_val, act_val);
  	}
  return poll_check;
}



U32 atlas_read_reg(WORD Base_Addr1,int reg_num) 
{
	WORD read_data=0;
	WORD read_inst;
	int i=0;
	// building the reading word
	read_inst=0x00000000;
	read_inst= (read_inst | (reg_num << 25));
	
	// reading from atlas
 	 mem32_write(Base_Addr1 + 0x04, read_inst);	  
 	 mem32_write (Base_Addr1 + 0x08, 0x00071fc7);
	 while(cspi_polling (Base_Addr1 + 0x08, 0x00071fc3) != 1) {
         i++;
	 if(i>100) printf("There is a problem");
  	}
	 read_data=mem32_read(Base_Addr1);
	
	return read_data;
}

void atlas_write_reg(WORD Base_Addr1,int reg_num, WORD data) 
{
	WORD read_data=0;
	WORD read_inst;
	int i=0;
	// the data is only 24 bits (ATLAS)
	data=0x00FFFFFF & data;
	

	// building the reading word
	read_inst=0x00000000;
	read_inst= (read_inst | (reg_num << 25));
	read_inst=(read_inst | 0x80000000);
	read_inst=(read_inst | data);
 	
	// reading from atlas
 	 mem32_write(Base_Addr1 + 0x04, read_inst);	  
 	 mem32_write (Base_Addr1 + 0x08, 0x00071fc7);
	 
	 while(cspi_polling (Base_Addr1 + 0x08, 0x00071fc3) != 1) 
	 { 
         i++;
	     if(i>100) printf("There is a problem");
  	}
	
	read_data=mem32_read(Base_Addr1); //  flush the receive FIFO

	return;

}




void init_atlas_specific(void)
{

  WORD temp ;

     set_iomux_cspi2_via_dedicated_pins ();

     mem32_write (Base_Addr1 + 0x0c, 0x00000030);	// RH & RF enabled
     mem32_write (Base_Addr1 + 0x08, 0x00071fc3);	// initialization of CSPI

      	atlas_write_reg(Base_Addr1,51, 0xf20001); // en lights
      	wait(90000000);
      	atlas_write_reg(Base_Addr1,51, 0x0); // dis lights
  
	// start backlight

	temp = atlas_read_reg(Base_Addr1, 29);
	atlas_write_reg(Base_Addr1,29, temp | 0x100000);// make sure boost switcher is on
	temp = atlas_read_reg(Base_Addr1, 29);
	//printf("sw3 control %x\n", temp);
	
	temp = atlas_read_reg(Base_Addr1, 51);
	atlas_write_reg(Base_Addr1,51, temp | 0x3); 
	temp = atlas_read_reg(Base_Addr1, 51);
	//printf("after setting leds %x\n", temp);

	temp = atlas_read_reg(Base_Addr1, 53);
	atlas_write_reg(Base_Addr1,53, 0); // en lights
	atlas_write_reg(Base_Addr1,53,  0x1 | (0x8<<9)); // en lights
	temp = atlas_read_reg(Base_Addr1, 53);

	atlas_write_reg(Base_Addr1, 30, (atlas_read_reg(Base_Addr1, 30) & ~(7<<6)) | 6<<6); // 2.7V on Atlas interface for CSPI3_SS1

	
}



int main(void)
{
 int rc=0;

	printf ("START_TEST\n");

	iomux_config() ; 	

//	init_atlas_specific() ;	


	CSPI_Init() ;

	test() ;
	

	test_exit (rc);

	return rc;
}


