forkd

Dependencies:   mbed

Fork of LG2 by Dmitry Kovalev

host/Source/App/InputOutput_oldSPI.c

Committer:
Kovalev_D
Date:
2016-02-03
Revision:
23:12e6183f04d4

File content as of revision 23:12e6183f04d4:

#include "InputOutput.h"
#include "lpc17xx.h"

INPUT Input;
OUTPUT Output;

volatile uint32_t I2CMasterState = I2C_IDLE;
volatile uint32_t I2CMasterBuffer[I2C_WRITELENGTH];

int ExchangeErr = 0;  

/******************************************************************************
** Function name:		G_Photo_Exchange
**
** Descriptions:		Driver for I2C exchange 
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
#if defined  I2C0
void G_Photo_Exchange(void) 
{
  		 uint32_t StatValue;
  static uint32_t WrIndex;
  static  int32_t time_out = TIMEOUT;

 if (I2CMasterState)
  return;							//e.transmitting is not active, go away

    if (--time_out < 0) 		   //e. valid time period elapsed, go away
	{
	   	time_out = TIMEOUT;
	  	I2CMasterState = I2C_IDLE;	 	//e. timer elapsed, go away
		LPC_I2C0->CONSET = I2CONSET_STO;      //e. Set Stop flag 	
        LPC_I2C0->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC;  
		return;	
	}
	else if (!(LPC_I2C0->CONSET & I2CONSET_SI))		//e. state of I2C bus has not been changed
   		return;

	StatValue = LPC_I2C0->STAT;

  switch ( StatValue )
  {
	case 0x08:			// A Start condition is issued (write data for the first potentiometer) 
	WrIndex = 0;
	time_out = TIMEOUT;  //e. enable countdown
	LPC_I2C0->DAT = I2CMasterBuffer[WrIndex++];	   //e. send address
	LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //e .clear interrupt bit and start bit
	break;
	
	case 0x10:			// A repeated started is issued (write data for the second potentiometer) 
	LPC_I2C0->DAT = I2CMasterBuffer[WrIndex++];	   //e. send address
	LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //e .clear interrupt bit and start bit
	break;

	case 0x18:			//e. Regardless, it's a ACK after slave address reading
	LPC_I2C0->DAT = I2CMasterBuffer[WrIndex++];  //e. send another byte
	LPC_I2C0->CONCLR = I2CONCLR_SIC;	//e. clear interrupt bit
	break;

	case 0x28:	//e. Regardless it's a ACK after data byte 
	if  (WrIndex == I2C_WRITELENGTH) //e. we have transmitted the data for the B potentiometer
	{  
	  I2CMasterState = I2C_IDLE;
	 LPC_I2C0->CONSET = I2CONSET_STO;      //e. Set Stop flag
	}
	else if (WrIndex == 3)
	{
	 LPC_I2C0->CONSET = I2CONSET_STA; 
	}
	else
	{
	  LPC_I2C0->DAT = I2CMasterBuffer[WrIndex++];  //e. send another byte	
	}
	LPC_I2C0->CONCLR = I2CONCLR_SIC;	//e. clear interrupt bit
	break;

	case 0x20:							  //e. no aknowledgement after address transmitting
	case 0x30:							  //e. no aknowledgement after data block transmitting
    LPC_I2C0->CONSET = I2CONSET_STO;      //e. Set Stop flag 
	LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); 
	I2CMasterState = I2C_IDLE;	  //e. fix new state
	break;
  }
  return;
}
#else
void G_Photo_Exchange(void) 
{
  static uint32_t WrIndex;
  		 uint32_t StatValue;
  static int time_out = TIMEOUT;

 if (I2CMasterState)
  return;							//e.transmitting is not active, go away

    if (--time_out < 0) 		   //e. valid time period elapsed, go away
	{
	   	time_out = TIMEOUT;
	  	I2CMasterState = I2C_TIME_OUT;	 //e. timer elapsed, go away
		LPC_I2C2->CONSET = I2CONSET_STO;      //e. Set Stop flag 	
        LPC_I2C2->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC;  
		return;	
	}
	else if (!(LPC_I2C2->CONSET & I2CONSET_SI))		//e. state of I2C bus has not been changed
   		return;

	StatValue = LPC_I2C2->STAT;

  switch ( StatValue )
  {
	case 0x08:			// A Start condition is issued (write data for the first potentiometer) 
	 WrIndex = 0;
	time_out = TIMEOUT;  //e. enable countdown
	LPC_I2C2->DAT = I2CMasterBuffer[WrIndex++];	   //e. send address
	LPC_I2C2->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //e .clear interrupt bit and start bit
	break;
	
	case 0x10:			// A repeated started is issued (write data for the second potentiometer) 
	LPC_I2C2->DAT = I2CMasterBuffer[WrIndex++];	   //e. send address
	LPC_I2C2->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //e .clear interrupt bit and start bit
	break;

	case 0x18:			//e. Regardless, it's a ACK after slave address reading
	LPC_I2C2->DAT = I2CMasterBuffer[WrIndex++];  //e. send another byte
	LPC_I2C2->CONCLR = I2CONCLR_SIC;	//e. clear interrupt bit
	break;

	case 0x28:	//e. Regardless it's a ACK after data byte 
	if  (WrIndex == I2C_WRITELENGTH) //e. we have transmitted the data for the B potentiometer
	{  
	  I2CMasterState = I2C_IDLE;		    //e. fix new state (release bus) 
	 LPC_I2C2->CONSET = I2CONSET_STO;      //e. Set Stop flag
	}
	else if (WrIndex == 3)
	{
	 LPC_I2C2->CONSET = I2CONSET_STA; 
	}
	else
	{
	  LPC_I2C2->DAT = I2CMasterBuffer[WrIndex++];  //e. send another byte	
	}
	LPC_I2C2->CONCLR = I2CONCLR_SIC;	//e. clear interrupt bit
	break;

	case 0x20:							  //e. no aknowledgement after address transmitting
	case 0x30:							  //e. no aknowledgement after data block transmitting
    LPC_I2C2->CONSET = I2CONSET_STO;      //e. Set Stop flag 
	LPC_I2C2->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); 
	I2CMasterState = I2C_IDLE;	  		  //e. fix new state  (release)
	break;
  }
  return;
}
#endif
/******************************************************************************
** Function name:		DAC_Out_ADC_Input
**
** Descriptions:		Loading data to DACs and initialization of ADC reading 
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void DAC_Out_ADC_Input()
{
 int i, Dummy = Dummy;

  //-------------------------loading data from ADC to buffer---------------------------------------
     i = BYTES_FOR_ADCs;
   	ExchangeErr &= ~ADC_ERR_MSK;		   //reset ADC bit of error register;

  if (LPC_SSP0->SR & SSP_BUSY)	   		   //if exchanging is activing, error
   {
     	ExchangeErr |= ADC_ERR_MSK;		   //reset DAC bit of error register;
   } 
  else
 
    while ((i-- > 0) && (LPC_SSP0->SR & TX_SSP_notFULL)) 	//receiving has finished, initiate a new one	   
	 LPC_SSP0->DR = 0xFF; 
  /*
{	LPC_SSP0->DR = 0x80;
	LPC_SSP0->DR = 0x01;
	LPC_SSP0->DR = 0xC0;
	LPC_SSP0->DR = 0x03;
	LPC_SSP0->DR = 0xE0;
	LPC_SSP0->DR = 0x07;
	LPC_SSP0->DR = 0xF0;
	LPC_SSP0->DR = 0x0F; }*/
// ------------------------loading data to DACs--------------------------------------------------
  	ExchangeErr &= ~DAC_ERR_MSK;		   //reset DAC bit of error register;
	i= BYTEs_FOR_DACs >> 1;
  if (LPC_SSP1->SR & SSP_BUSY)	//if exchanging is activing, error
  {
  	 ExchangeErr |= DAC_ERR_MSK;
  }
  else 	
  	while ((i-->0) && (LPC_SSP1->SR & TX_SSP_notFULL))	  //load new data to DAC
  	{
  		LPC_SSP1->DR = (Output.ArrayOut[i]>>8)& 0xFF;
     if (LPC_SSP1->SR & TX_SSP_notFULL)
 	    LPC_SSP1->DR = Output.ArrayOut[i] & 0xFF; 
	}  

/*  {	LPC_SSP1->DR = 0x80;
	LPC_SSP1->DR = 0x01;
	LPC_SSP1->DR = 0xC0;
	LPC_SSP1->DR = 0x03;
	LPC_SSP1->DR = 0xE0;
	LPC_SSP1->DR = 0x07;
	LPC_SSP1->DR = 0xF0;
	LPC_SSP1->DR = 0x0F; } */

  if (i != 0xFFFFFFFF)
     {
  	 	ExchangeErr |= DAC_ERR_MSK;
  	 }
}
/******************************************************************************
** Function name:		ADC_Out_DAC_Input
**
** Descriptions:		Reading data from ADC and initialization of DAC writing
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void ADC_Out_DAC_Input()
{ 
		   int i = 0, Dummy;
	static int timeDither = 0;
	Dummy = Dummy;

  //++++++++++++++++++++++++++  Dither_simulation   ++++++++++++++++++++++++++++++++++++++++++++++++
 
   if (++timeDither>(LPC_MCPWM->LIM0/50))
   {
     LPC_MCPWM->INTF_SET |= 1;
	 timeDither = 0;
   }	
   //----------------------read receiver buffer of DAC--------------------------------------------
   ExchangeErr &= ~DAC_ERR_MSK;

  if (LPC_SSP1->SR & SSP_BUSY)							//if exchanging is active, error
  {
  	ExchangeErr |= DAC_ERR_MSK;
  }
  else													//exchanging has finished, read buffer
  {	
   while (LPC_SSP1->SR & RX_SSP_notEMPT)
   {
     Dummy = LPC_SSP1->DR;
	  i++;
   } 
   	
   if (i != BYTEs_FOR_DACs)
   {
	  ExchangeErr |= DAC_ERR_MSK;
   }
  }

   //---------------------read data from ADC buffer---------------------------------------------
 	  i = BYTES_FOR_ADCs >> 1;
  ExchangeErr &= ~ADC_ERR_MSK;

  if (LPC_SSP0->SR & SSP_BUSY)	  						//if exchanging is active, error
  {
    if ((LPC_SSP0->SR & TX_SSP_EMPT)==0)	
  	ExchangeErr |= ADC_ERR_MSK;
  }
  else							 						//exchanging has finished, read buffer
  {	
   while ((i-- > 0)&& (LPC_SSP0->SR & RX_SSP_notEMPT) )	 //read buffer while data present 
     {
	  	Input.ArrayIn[i] = ((LPC_SSP0->DR & 0xFF) << 8);
	 if (LPC_SSP0->SR & RX_SSP_notEMPT)   
	  	Input.ArrayIn[i] |= (LPC_SSP0->DR & 0xFF);
	 else
	   break;
	 }
   if (i != 0xFFFFFFFF)
   	 ExchangeErr |= ADC_ERR_MSK; 
  }
}
/******************************************************************************
** Function name:		G_Photo_Init
**
** Descriptions:		Initialization of exchange with digital potentiometers
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
#if !defined I2C0
void G_Photo_Init( void ) 
{
  LPC_SC->PCONP |= (1 << 26);	//e. enable I2C interface
   //e. by default sync frequency is CCLK/4 (see PCLKSEL1[21:20])

  //e. set P0.10 and P0.11 to I2C2 SDA and SCL 
  LPC_PINCON->PINSEL0 &= ~((0x03<<20)|(0x03<<22));	//e. clear 
  LPC_PINCON->PINSEL0 |= ((0x02<<20)|(0x02<<22));	//e. set SDA2, SCL2
  LPC_PINCON->PINMODE0 &= ~((0x03<<20)|(0x03<<22));	//e. clear 
  LPC_PINCON->PINMODE0 |= ((0x02<<20)|(0x2<<22));	//e. No pull-up no pull-down 
  LPC_PINCON->PINMODE_OD0 |= ((0x01<<10)|(0x1<<11));//e. switch SDA2, SCL2	to open drain mode
 
  //--- Clear flags ---
  LPC_I2C2->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;    

  //--- Set registers for transmition rate = PCLK/(I2SCLL_SCLL+I2SCLH_SCLH)---
  LPC_I2C2->SCLL   = I2SCLL_SCLL;
  LPC_I2C2->SCLH   = I2SCLH_SCLH;

  	I2CMasterBuffer[0] = A_ADDRESS;
	I2CMasterBuffer[1] = WRITE_CMD;
	I2CMasterBuffer[3] = B_ADDRESS;
	I2CMasterBuffer[4] = WRITE_CMD;

  LPC_I2C2->CONSET = I2CONSET_I2EN;
  return;
} 
#else
void G_Photo_Init(void ) 
{
  LPC_SC->PCONP |= (1 << 19);

  /* set PIO0.27 and PIO0.28 to I2C0 SDA and SCK */
  /* function to 01 on both SDA and SCK. */
  LPC_PINCON->PINSEL1 &= ~0x03C00000;
  LPC_PINCON->PINSEL1 |= 0x01400000;	
 
  /*--- Clear flags ---*/
  LPC_I2C0->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;    

  /*--- Reset registers ---*/
  LPC_I2C0->SCLL   = I2SCLL_SCLL;
  LPC_I2C0->SCLH   = I2SCLH_SCLH;

 	I2CMasterBuffer[0] = A_ADDRESS;
	I2CMasterBuffer[1] = WRITE_CMD;
	I2CMasterBuffer[3] = B_ADDRESS;
	I2CMasterBuffer[4] = WRITE_CMD;

  LPC_I2C0->CONSET = I2CONSET_I2EN;

}
#endif
/******************************************************************************
** Function name:		DAC_ADC_Exchange_Init
**
** Descriptions:		Initialization of data exchange with DACs and ADCs
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void DAC_ADC_Exchange_Init()
{
   int Dummy;

   Dummy = Dummy;

  /* Enable AHB clock to the SSP0, SSP1 */
 // LPC_SC->PCONP |= (0x1<<21);
 // LPC_SC->PCONP |= (0x1<<10);

  /* Further divider is needed on SSP0,SSP1 clock. Using default divided by 4 */
  LPC_SC->PCLKSEL1 &= ~(0x3<<10);
  LPC_SC->PCLKSEL0 &= ~(0x3<<20);

  /* P0.15~0.18 as SSP0 */
  LPC_PINCON->PINSEL0 &= ~(0x3UL<<30);
  LPC_PINCON->PINSEL0 |=  (0x2UL<<30);
  LPC_PINCON->PINSEL1 &= ~((0x3<<0)|(0x3<<2)|(0x3<<4));
  LPC_PINCON->PINSEL1 |=  ((0x2<<0)|(0x2<<2)|(0x2<<4));

  LPC_PINCON->PINMODE0 &= ~(0x3UL<<30);
  LPC_PINCON->PINMODE0 |=  (0x3UL<<30);
  LPC_PINCON->PINMODE1 &= ~((0x3<<2)|(0x3<<4));
  LPC_PINCON->PINMODE1 |=  ((0x3<<2)|(0x3<<4));

  /* P0.6~0.9 as SSP1 */
  LPC_PINCON->PINSEL0 &= ~((0x3<<12)|(0x3<<14)|(0x3<<16)|(0x3<<18));
  LPC_PINCON->PINSEL0 |=  ((0x2<<12)|(0x2<<14)|(0x2<<16)|(0x2<<18));
  LPC_PINCON->PINMODE0 &= ~((0x3<<16)|(0x3<<12)|(0x3<<14)|(0x3<<18));
  LPC_PINCON->PINMODE0 |= ((0x3<<16)|(0x3<<14)|(0x3<<18));

  /* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 2*/
  LPC_SSP0->CR0 = 0x0207;
  LPC_SSP1->CR0 = 0x0207;

  /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
  LPC_SSP0->CPSR = 0x2;
  LPC_SSP1->CPSR = 0x2;	 //so, SSPfreq = PCLK/(2*(2+1))	= 4.13 MHz
	
  LPC_SSP0->CR1 = SSPCR1_SSE;
  LPC_SSP1->CR1 = SSPCR1_SSE;

  while (LPC_SSP0->SR & SSP_BUSY);
  while (LPC_SSP1->SR & SSP_BUSY);

   while (LPC_SSP0->SR & RX_SSP_notEMPT)  /* clear the RxFIFO */
	Dummy = LPC_SSP0->DR;		

   while (LPC_SSP1->SR & RX_SSP_notEMPT)
	Dummy = LPC_SSP1->DR;		/* clear the RxFIFO */
}
/******************************************************************************
** Function name:		Out_G_photo
**
** Descriptions:		Start of potentiometer data writing process
**
** parameters:			pointer to gain factors
** Returned value:		None
** 
******************************************************************************/
void  Out_G_photo(uint32_t Ph_A, uint32_t Ph_B)
{
	I2CMasterBuffer[2] = Ph_A;
	I2CMasterBuffer[5] = Ph_B;	
#if defined I2C0
	LPC_I2C0->CONSET = I2CONSET_STA;	// Set Start flag 
#else
	LPC_I2C2->CONSET = I2CONSET_STA;	// Set Start flag 
#endif
  	  I2CMasterState = I2C_BUSY;  
 }