/*********************************************************************
 *                    Flowcode SPI Component Code
 *
 * File: SPI_Code.c
 *
 * (c) 2007 Matrix Multimedia Ltd.
 * http://www.matrixmultimedia.com
 *
 * Software License Agreement
 *
 * The software supplied herewith by Matrix Multimedia Ltd (the
 * “Company”) for its Flowcode graphical programming language is
 * intended and supplied to you, the Company’s customer, for use
 * solely and exclusively on the Company's products. The software
 * is owned by the Company, and is protected under applicable
 * copyright laws. All rights are reserved. Any use in violation
 * of the foregoing restrictions may subject the user to criminal
 * sanctions under applicable laws, as well as to civil liability
 * for the breach of the terms and conditions of this licence.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 * Changelog:
 *
 *  date  | by | description
 * -------+----+-----------------------------------------------------
 * 110607 | BR | Created
 * 090707 | ST | Amended and incorporated with OCX component
 * 160108 | BR | Added Error Message
 * 300608 | BR | Ammended the FRAM functions to assign portb when using the BCB SPI port
 *        |    |
 *        |    |
 *
 *
 *
 ********************************************************************/

/*********************************************************************

 Return & parameter types:
   void
   char
   short
   char*

 Pin directions:
   0 = OUTPUT
   2 = INPUT
   3 = BIDIRECTIONAL

	'%a = SPI_DAC_EN
	'%b = SPI_FRM_EN
	'%c = SPI_SSPM
	'%d = SPI_CKP
	'%e = SPI_CKE
	'%f = SPI_SMP
	'%g = CompID


**********************************************************************

[Settings]
CLSID={94B3CE1A-BDFF-4A7D-921E-1F44931A264C}
IsAnalogue=0
MultipleAllowed=0
Description=SPI Flowcode Component

**********************************************************************

[MacroNames]
Count=11
1=GetDefines
2=SPI_Init
3=SPI_Uninit
4=SPI_Send_Char
5=SPI_Get_Char
6=DAC_Send_Char
7=NVM_Send_Char
8=NVM_Get_Char
9=FramOutput
10=EnableFRAM
11=DisableFRAM

[MacroReturns]
1=void
2=void
3=void
4=void
5=char
6=void
7=void
8=char
9=char
10=void
11=void

[MacroIsPrivate]
1=1
2=0
3=0
4=0
5=0
6=0
7=0
8=0
9=0
10=0
11=0

[MacroParameters_GetDefines]
Count=0

[MacroParamTypes_GetDefines]

[MacroParameters_SPI_Init]
Count=0

[MacroParamTypes_SPI_Init]

[MacroParameters_SPI_Uninit]
Count=0

[MacroParamTypes_SPI_Uninit]

[MacroParameters_SPI_Send_Char]
Count=1
1=Char

[MacroParamTypes_SPI_Send_Char]
1=char

[MacroParameters_SPI_Get_Char]
Count=0

[MacroParamTypes_SPI_Get_Char]

[MacroParameters_DAC_Send_Char]
Count=1
1=Char

[MacroParamTypes_DAC_Send_Char]
1=char

[MacroParameters_NVM_Send_Char]
Count=3
1=hi_addr
2=lo_addr
3=Char

[MacroParamTypes_NVM_Send_Char]
1=char
2=char
3=char

[MacroParameters_NVM_Get_Char]
Count=2
1=hi_addr
2=lo_addr

[MacroParamTypes_NVM_Get_Char]
1=char
2=char

[MacroParameters_FramOutput]
Count=1
1=Char

[MacroParamTypes_FramOutput]
1=char

[MacroParameters_EnableFRAM]
Count=0

[MacroParamTypes_EnableFRAM]

[MacroParameters_DisableFRAM]
Count=0

[MacroParamTypes_DisableFRAM]

 ********************************************************************/

/********************************************************************
 * ADDITIONAL CODE
 ********************************************************************/

/*InitialisationCode_Start*/
/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/


void GetDefines()
{
/*Macro_GetDefines_Start*/

}  //Dummy end of function to allow defines to be added correctly

//SPI COMPONENT DEFINES
#define SPI_DAC_EN 	%a
#define SPI_FRM_EN 	%b

#define SPI_SSPM 	%c
#define SPI_CKP 	%d
#define SPI_CKE 	%e
#define SPI_SMP 	%f

//FRAM commands
#define FRAM_WREN  	6
#define FRAM_WRDI  	4
#define FRAM_RDSR  	5
#define FRAM_WRSR  	1
#define FRAM_READ  	3
#define FRAM_WRITE 	2

// Dummy function to close the defines section off
void %g_Dummy_Function();
void %g_Dummy_Function()
{

/*Macro_GetDefines_End*/
}


/********************************************************************
 * FUNCTIONS
 ********************************************************************/

void SPI_Init()
{
/*Macro_SPI_Init_Start*/

	//GetSPI_InitCode
	#ifndef MX_SPI
	    #pragma error "Chip does not have SPI capability"
	#endif

	//initialise spi
	#ifdef MX_SPI_B
	    set_bit(trisb,MX_SPI_SDI);
	    clear_bit(trisb,MX_SPI_SDO);
	    clear_bit(trisb,MX_SPI_SCK);
	    clear_bit(trisb,SPI_DAC_EN);
	    clear_bit(trisb,SPI_FRM_EN);

	    //disable SPI devices
	    set_bit(portb, SPI_DAC_EN);
	    set_bit(portb, SPI_FRM_EN);
	#endif

	#ifdef MX_SPI_C
	    set_bit(trisc,MX_SPI_SDI);
	    clear_bit(trisc,MX_SPI_SDO);
	    clear_bit(trisc,MX_SPI_SCK);
	    clear_bit(trisc,SPI_DAC_EN);
	    clear_bit(trisc,SPI_FRM_EN);

	    //disable SPI devices
	    set_bit(portc, SPI_DAC_EN);
	    set_bit(portc, SPI_FRM_EN);
	#endif

	#ifdef MX_SPI_BCB
	    set_bit(trisb,MX_SPI_SDI);
		clear_bit(trisc,MX_SPI_SDO);
		clear_bit(trisb,MX_SPI_SCK);
		clear_bit(trisb,SPI_DAC_EN);
		clear_bit(trisb,SPI_FRM_EN);

		//disable SPI devices
		set_bit(portb, SPI_DAC_EN);
		set_bit(portb, SPI_FRM_EN);
	#endif

	sspstat = SPI_CKE | SPI_SMP;

  #ifdef SSPCON
	sspcon = SPI_SSPM | SPI_CKP;
	set_bit(sspcon, SSPEN);
  #endif
  #ifdef SSPCON1
	sspcon1 = SPI_SSPM | SPI_CKP;
	set_bit(sspcon1, SSPEN);
  #endif

/*Macro_SPI_Init_End*/
}

void SPI_Uninit()
{
/*Macro_SPI_Uninit_Start*/
	//GetSPI_UninitCode
	#ifndef MX_SPI
	    #pragma error "Chip does not have SPI capability"
	#endif

  #ifdef SSPCON
	clear_bit(sspcon, SSPEN);
  #endif
  #ifdef SSPCON1
	clear_bit(sspcon1, SSPEN);
  #endif

/*Macro_SPI_Uninit_End*/
}

void SPI_Send_Char(char Char)
{
/*Macro_SPI_Send_Char_Start*/
	//GetSPI_Send_CharCode
	#ifndef MX_SPI
	    #pragma error "Chip does not have SPI capability"
	#endif

	//send the Char
	sspbuf = Char;

	//wait until sspbuf is empty
	while ((sspstat & 0x01) == 0);
/*Macro_SPI_Send_Char_End*/
}

char SPI_Get_Char()
{
/*Macro_SPI_Get_Char_Start*/
	//GetSPI_Get_CharCode
	char retVal = 0;
	#ifndef MX_SPI
	    #pragma error "Chip does not have SPI capability"
	#endif

	//send a dummy Char
	sspbuf = 0x5A;

	//wait until sspbuf is empty
	while ((sspstat & 0x01) == 0);

	//receive the Char
	retVal = sspbuf;

	return (retVal);
/*Macro_SPI_Get_Char_End*/
}

void DAC_Send_Char(char Char)
{
/*Macro_DAC_Send_Char_Start*/
	//GetDAC__Send_Char Code
	#ifndef MX_SPI
	    #pragma error "Chip does not have SPI capability"
	#endif

	char dac_val;

	//enable dac
	#ifdef MX_SPI_B
	    clear_bit(portb, SPI_DAC_EN);
	#endif
	#ifdef MX_SPI_C
	    clear_bit(portc, SPI_DAC_EN);
	#endif
	#ifdef MX_SPI_BCB
		clear_bit(portb, SPI_DAC_EN);
	#endif

	dac_val = (Char & 0xF0) >> 4;
	sspbuf = dac_val;
	delay_10us(1);

	dac_val = (Char & 0x0F) << 4;
	sspbuf = dac_val;
	delay_10us(1);

	//disable dac
	#ifdef MX_SPI_B
	    set_bit(portb, SPI_DAC_EN);
	#endif
	#ifdef MX_SPI_C
	    set_bit(portc, SPI_DAC_EN);
	#endif
	#ifdef MX_SPI_BCB
		set_bit(portb, SPI_DAC_EN);
	#endif
/*Macro_DAC_Send_Char_End*/
}

void NVM_Send_Char(char hi_addr, char lo_addr, char Char)
{
/*Macro_NVM_Send_Char_Start*/
	//GetNVM_Send_CharCode
	#ifndef MX_SPI
	    #pragma error "Chip does not have SPI capability"
	#endif

	//disable interrupts
	clear_bit(intcon, GIE);
	//enable writes
	FCD_SPI0_EnableFRAM();
	FCD_SPI0_FramOutput(FRAM_WREN);
	FCD_SPI0_DisableFRAM();

	//delay here???
	//delay_us(100);

	//send write-fram command, address and data
	FCD_SPI0_EnableFRAM();
	FCD_SPI0_FramOutput(FRAM_WRITE);
	FCD_SPI0_FramOutput(hi_addr);
	FCD_SPI0_FramOutput(lo_addr);
	FCD_SPI0_FramOutput(Char);
	FCD_SPI0_DisableFRAM();

	//re-enable interrupts
	set_bit(intcon, GIE);
/*Macro_NVM_Send_Char_End*/
}

char NVM_Get_Char(char hi_addr, char lo_addr)
{
/*Macro_NVM_Get_Char_Start*/
	//GetNVM_Send_CharCode
	char retVal;

	#ifndef MX_SPI
	    #pragma error "Chip does not have SPI capability"
	#endif

	//disable interrupts
	clear_bit(intcon, GIE);

	FCD_SPI0_EnableFRAM();

	//send read-fram command and address
	FCD_SPI0_FramOutput(FRAM_READ);
	FCD_SPI0_FramOutput(hi_addr);
	FCD_SPI0_FramOutput(lo_addr);

	//read the data
	retVal = FCD_SPI0_FramOutput(0x5A);  //don't care byte of 0x5A

	FCD_SPI0_DisableFRAM();

	//re-enable interrupts
	set_bit(intcon, GIE);

	return(retVal);
/*Macro_NVM_Get_Char_End*/
}

char FramOutput(char Char)
{
/*Macro_FramOutput_Start*/
	//GetFramOutputCode
	char retVal;

	sspbuf = Char;

	//wait until byte has been received
	while ((sspstat & 0x01) == 0);

	retVal = sspbuf;

	return (retVal);
/*Macro_FramOutput_End*/
}

void EnableFRAM()
{
/*Macro_EnableFRAM_Start*/
	//enable FRAM
	#ifdef MX_SPI_B
	    clear_bit(portb, SPI_FRM_EN);
	#endif
	#ifdef MX_SPI_C
	    clear_bit(portc, SPI_FRM_EN);
	#endif
	#ifdef MX_SPI_BCB
		clear_bit(portb, SPI_FRM_EN);
	#endif
/*Macro_EnableFRAM_End*/
}

void DisableFRAM()
{
/*Macro_DisableFRAM_Start*/
	//disable FRAM
	#ifdef MX_SPI_B
	    set_bit(portb, SPI_FRM_EN);
	#endif
	#ifdef MX_SPI_C
	    set_bit(portc, SPI_FRM_EN);
	#endif
	#ifdef MX_SPI_BCB
		set_bit(portb, SPI_FRM_EN);
	#endif
/*Macro_DisableFRAM_End*/
}