// CSPITest.cpp : Defines the entry point for the application.
//

#include <stdio.h>
#include <stdlib.h>
#include "stdafx.h"
#include "common.h"
#include "config_pad_mode.h"
#include "iomuxc_mem_map.h" 
#include "CSPITest.h"

#define REG_CSPI3_CONREG (*(volatile long*) CSPI3_CONREG)

WORD get_mixed_mode (WORD byte_in_reg,WORD output_mode,WORD input_mode) {
   WORD mixed_mode;

   switch (byte_in_reg) {
      case  0:mixed_mode=(input_mode+output_mode);
			  break;
      case  1:mixed_mode=(input_mode+output_mode)*0x100;
			  break;
      case  2:mixed_mode=(input_mode+output_mode)*0x10000; 
   	 	      break;
      case  3:mixed_mode=(input_mode+output_mode)*0x1000000; 
			  break;
   }  
   return mixed_mode;
}		

void reg32_write_mask(WORD addr , WORD wdata , WORD mask) 
{ //{{{2
   WORD	masked_wdata,rdata;

   rdata=reg32_read(addr);
   masked_wdata=(((~mask)&rdata)|(mask&wdata));
   reg32_write(addr,masked_wdata);
} //2}}}

void config_pad_mode(WORD pad_name,WORD output_mode,WORD input_mode) {
   WORD wdata,reg_addr,offset;
   int pad_offset;

   pad_offset=(328-pad_name)/4;
   offset=pad_offset*4;
   reg_addr=IOMUXC_BASE_ADDR+offset+0xc;
   
   switch (pad_name%4) {
	  case 0: wdata=get_mixed_mode(0,output_mode,input_mode);
              reg32_write_mask(reg_addr,wdata,BYTE0_MASK);
			  break;
	  case 1: wdata=get_mixed_mode(3,output_mode,input_mode);
              reg32_write_mask(reg_addr,wdata,BYTE3_MASK);
			  break;
	  case 2: wdata=get_mixed_mode(2,output_mode,input_mode);
              reg32_write_mask(reg_addr,wdata,BYTE2_MASK);
			  break;
	  case 3: wdata=get_mixed_mode(1,output_mode,input_mode);
              reg32_write_mask(reg_addr,wdata,BYTE1_MASK);
			  break;
      default : 
	break;
//verilog_trigger(arm_vt_error);
   }
}

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 set_iomux_cspi1_via_dedicated_pins (){
    reg32_write(SW_MUX_CTL_CSPI1_MOSI_CSPI1_MISO_CSPI1_SS0_CSPI1_SS1,0x12121212);
    reg32_write_mask(SW_MUX_CTL_CSPI1_SS2_CSPI1_SCLK_CSPI1_SPI_RDY_CSPI2_MOSI,0x12121200,0xffffff00);
}

void set_iomux_cspi2_via_dedicated_pins (){
    reg32_write_mask(SW_MUX_CTL_CSPI1_SS2_CSPI1_SCLK_CSPI1_SPI_RDY_CSPI2_MOSI,0x00000012,0x000000ff);
    reg32_write(SW_MUX_CTL_CSPI2_MISO_CSPI2_SS0_CSPI2_SS1_CSPI2_SS2,0x12121212);
    reg32_write_mask(SW_MUX_CTL_CSPI2_SCLK_CSPI2_SPI_RDY_RXD1_TXD1,0x12120000,0xffff0000);
}

void set_iomux_cspi3_via_dedicated_pins (){
    reg32_write_mask(SW_MUX_CTL_ATA_RESET_B_CE_CONTROL_CLKSS_CSPI3_MOSI,0x00000012,0x000000ff);
    reg32_write_mask(SW_MUX_CTL_CSPI3_MISO_CSPI3_SCLK_CSPI3_SPI_RDY_TTM_PAD,0x12121200,0xffffff00);
}

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 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 (say, pin9 of J15)
// SPI3 MISO (pin 8 of J15) should be tied to SPI1 MISO (pin C3 of J17)
// SPI3 MOSI (pin 4 of J15) should be tied to SPI1 MOSI (pin C2 of J17)


//	enable_IRQ() ; 
	
// pause just for test if our exceptions will occur

//	for ( k = 0; k < 10 ; k++ ) printf ("*") ;
			
	mem32_write (CSPI3_TXDATA, 0x00000321);	
  	
  	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)) ; 	
}

int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR    lpCmdLine,
					int       nCmdShow)
{
	printf ("START_TEST\n");

	iomux_config() ; 	
	CSPI_Init() ;
	test() ;

	return 0;
}

