fork

Dependencies:   mbed

Fork of LG by igor Apu

el_lin.c

Committer:
igor_v
Date:
2016-01-30
Revision:
0:8ad47e2b6f00
Child:
1:f2adcae3d304

File content as of revision 0:8ad47e2b6f00:


/**--------------File Info---------------------------------------------------------------------------------
** File name:           el_lin.c
** Last modified Date:  2011-08-22
** Last Version:        V1.00 
**--------------------------------------------------------------------------------------------------------
** Created by:          Electrooptica Incor.
** Created date:        2011-08-22
** Version:             V1.00
**--------------------------------------------------------------------------------------------------------       
*********************************************************************************************************/
#include "CyclesSync.h"
#include "CntrlGLD.h"
#include "el_lin.h"

#define UART1TEST
#define UART1REC
/*
struct {
	    uint32_t  rcv_num_byt; 
		uint32_t rcv_num_byt_old;
		uint32_t  rcv_Rdy;  
			char  rcv_copy[64];
		    char  rcv_buf[64];
		 int32_t rx_buf_copy;
		 int32_t rcv_byt_copy;       
  	  }RECIEVER;

struct {
		uint32_t trm_num_byt;
		uint32_t trm_rate;
    	uint32_t trm_cycl;
		uint32_t num_of_par;
			char trm_buf[64];
		   void* addr_param[16];
		uint32_t size_param[16];
		uint32_t trm_ena;
	   }TRANSMITTER;
*/
	    uint32_t  rcv_num_byt; 
		uint32_t rcv_num_byt_old;
		uint32_t  rcv_Rdy;  
			char  rcv_copy[64];
		    char  rcv_buf[64];
		 int32_t rx_buf_copy;
		 int32_t rcv_byt_copy;  
		
		uint32_t trm_num_byt;
		uint32_t trm_rate;    	
		uint32_t num_of_par;
			char trm_buf[64];
		   void* addr_param[16];
		uint32_t size_param[16];
		uint32_t trm_ena;

		uint32_t line_err;
		uint32_t line_sts;
		
 uint32_t EnablLength = 12;
 uint32_t LLI0_TypeDef[4];
 uint32_t LLI1_TypeDef[4];
 uint32_t EnablTx = 0x80;
 uint32_t EnablDMA = 0;
/******************************************************************************
** Function name:		DMA_IRQHandler
**
** Descriptions:		DMA interrupt handler
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
int check_lcc(void)           //e. CRC checking  //r.ïðîâåðêà êîíòðîëüíîé ñóììû
{
   int iCRC_calc, CRC_calc = 0, CRC_real;
 
  for (iCRC_calc = 1; iCRC_calc < (rcv_num_byt-2); iCRC_calc++)
    CRC_calc += rcv_buf[iCRC_calc];  
    
  CRC_real = (rcv_buf[rcv_num_byt-2] << 8) | rcv_buf[rcv_num_byt-1];
    
	return (CRC_real - CRC_calc);
}
 void  PacketSafing(void)
   {
  /* int j; static char rcv_buf_copy[16];
   	  for (j=2; j<rcv_num_byt; j++)
	  {
	  	if (rcv_buf[j] == 0xCC);		  
		  	rcv_buf_copy[0] = 0xCC;
	//	if ((rcv_buf[j] < 3) || (rcv_buf[j] == 0x1F))
	  }	 */
   }

/******************************************************************************
** Function name:		Line_1_Rcv
**
** Descriptions:		receive process preparation
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void Line_1_Rcv(void)                  
{  
  static int ToWaitEnd, ErrReg ;

	
	
	
	 while ((LPC_UART1->LSR & RecievBufEmpty) != 0)       //e. reciever contain some information                              
	 rcv_buf[rcv_num_byt++] = LPC_UART1->RBR;//÷òåíèå èíôîðìàöèè èç áóôåðà.
  
	 
	 
	 
	if (( ToWaitEnd > 25000))	//e. end part of packet is absent //r. íå äîæäàëèñü êîíöà ïàêåòà
   		 {
		  do
		 	 rcv_buf[--rcv_num_byt] = 0;
		  while(rcv_num_byt);
		  rcv_num_byt_old = rcv_num_byt;
#if defined UART1REC
			 LPC_UART1->FCR |= RX_FIFO_Reset; 
#else
  		 LPC_UART0->FCR |= RX_FIFO_Reset; 
#endif
	  //	L1_Rc_err (TIMEOUT_ERR);
	    	 ToWaitEnd = 0;
	 		 return;
		 }	
	  if (rcv_num_byt_old == rcv_num_byt)				  //e. we have not received any new bytes
 		 { 
		  if (ToWaitEnd) ToWaitEnd++;
		   return;
		 }
	  	rcv_num_byt_old = rcv_num_byt;

   if ((rcv_num_byt < 6) || ((rcv_num_byt & 0x0001) == 1))
    {
    ToWaitEnd++;
	 return;
    }		  										

  if ((!ToWaitEnd) && (rcv_num_byt > 1)) 					//e. the header of packet has not recieved //r. îæèäàåì íà÷àëî ïàêåòà				 			
  if ((rcv_buf[0] != 0xCC) || (( rcv_buf[1] > 2) && ( rcv_buf[1] != 0x1F)))  
   {   
  	 //	L1_Rc_err (HEADER_ERR);
		ErrReg |= 5;
		ToWaitEnd++;
		return;
   }
 //  if (ErrReg != 0)	//e. trying of recovering of packet //r. ñïàñåíèå ñëåäóþùåãî ïàêåòà
   //	  PacketSafing();


  if (rcv_num_byt == 6)
          {	 
		   if ((rcv_buf[2] == 0x0A) || (rcv_buf[2] == 0xE0) || (rcv_buf[2] == 0xE4) || (rcv_buf[2] == 0xE6) || (rcv_buf[2] == 0xE8))
			 {                      //e. packet length is not valid, so we have the error //r. îøèáêà ðàçìåðà ïàêåòà
        	   ToWaitEnd++;   	
			   return;
			 }

           }
  else  if (rcv_num_byt == 8)
  		  {
		   if ((rcv_buf[2] == 0xE0) || (rcv_buf[2] == 0xE4))
		    {
		     ToWaitEnd++;   	
			 return;
		    }
	      }
 if (check_lcc() != 0)  								//e. checksum is bad //r.êîíòðîëüíûå ñóììû íå ðàâíû
        {
		  
	       return;
        }
        else 												//e. cheksum is not bad //r.êîíòðîëüíûå ñóììû ðàâíû
        {
		  rcv_Rdy = 1;	  	
        }
	  ToWaitEnd = 0;

	  return;	
  
} 
/*
void L1_Rc_err (int Error)   //e. error fixing and reciever restart //r. ìîäóëü ôèêñàöèè îøèáêè è ïåðåçàïóñêà ïðèåìíèêà
{
	int temp;
  line_sts |= Error;
   	temp = Copy_SRgR & (~Rcv_Rdy);
   	 io_space_write(Sys_RgR, temp);
   	  temp |= Rcv_Rdy;
   	  asm("nop;");
   	   io_space_write(Sys_RgR, temp);
  return;	   
}
*/
	  
/******************************************************************************
** Function name:		transm_DAT
**
** Descriptions:		transmit process preparation
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/


void transm_DAT(void)
{
	uint32_t param, param_byte, CRC; 
     int32_t *trans_param;		
	 		 
	if ((LPC_UART1->LSR & TRANS_SHIFT_BUF_EMPTY))      //r. ïåðåäàþùèé áóôåð ïóñò
	   	if (!( LPC_GPDMACH1->CConfig & (1<<17)))
	  		LPC_GPIO2->FIOCLR |= 8;				//switch off UART1 driver

	if (trm_ena == 0)	
	{		
//	LPC_GPIO1->FIOCLR = (0x01<<30);							//r.ïåðåäà÷à òðåáóåòñÿ?
	 return;                                    //r. åñëè íåò, âîçâðàò				
	}									

	if (!(LPC_UART1->LSR & TRANS_SHIFT_BUF_EMPTY))     //r. ïåðåäàþùèé áóôåð ïóñò
  return;

	if ( LPC_GPDMACH1->CConfig & (1<<17))				//r. åñëè êàíàë ïåðåäà÷è çàíÿò, æäàòü
	  return;

//#if defined	UART1TEST
//	if (LPC_SC->DMAREQSEL == 0x8)							//e. DMA request from UART
//		LPC_GPIO2->FIOSET |= (1<<3);					//e. set enable UART bit
//#endif

	 trm_ena = 0; 									     //r. ñáðîñèòü ôëàã ðàçðåøåíèÿ ïåðåäà÷è	 
	 
	 trm_num_byt = 2;
	 
	 trm_buf[0] = 0x00dd;								//r. çàãîëîâîê ïàêåòà
      trm_buf[1] = Device_blk.Str.My_Addres;     	//r. àäðåñ ïðèáîðà
       
	  CRC = trm_buf[1];          					   //r.èíèöèàëèçàöèÿ ñ÷åò÷èêà êîíòðîëüíîé ñóììû 
	  for ( param = 0; param < num_of_par; param++)		 //r.öèêë ôîðìèðîâàíèÿ áëîêà äàííûõ ïàêåòà  
	  {		  		  	
	     trans_param = (int32_t *)addr_param[param];    //r. ÷òåíèå àäðåñà îäíîãî èç âûäàâàåìûõ â ïàêåòå ïàðàìåòðîâ	    
	    
	     for (param_byte = 0; param_byte < size_param[param]; param_byte++) 
	     {   
	    	if ( (param_byte & 0x0001) == 0 )			//r. ñ÷èòûâàåì ñòàðøèé áàéò 
	    	  trm_buf[trm_num_byt] = (*trans_param >> (8/**(size_param[param]-param_byte-1)*/)) & 0x00ff;	    	 //r.ðàçìåùåíèå ïåðåäàâàåìîãî ïàðàìåòðà â ïàêåòå  
	        else
	         {
	          trm_buf[trm_num_byt] = *trans_param & 0x00ff;
	           trans_param ++;								//r.ïåðåõîäèì ê ñëåäóþùåé ÿ÷åéêå ïàìÿòè
	         }
             CRC += trm_buf[trm_num_byt];					 //r. âû÷èñëåíèå òåêóùåé êîíòðîëüíîé ñóììû
               trm_num_byt++;								 //r. êîëè÷åñòâî áèò, îòïðàâëåííûõ â ïàêåò      
        } 
      }
	   trm_buf[trm_num_byt] = CRC >> 8;						 //r. çàïèñü êîíòðîëüíîé ñóììû â  ïàêåò
	    trm_buf[trm_num_byt+1] = CRC & 0x00ff;

             trm_num_byt += 2;

	LPC_GPDMACH1->CSrcAddr = (uint32_t)&trm_buf;
	
	LPC_GPDMACH1->CControl &= ~0xFFF;				//e. reset of numer bytes for transmitting
	LPC_GPDMACH2->CControl &= ~0xFFF;				//e. reset of numer bytes for transmitting
	
	LPC_GPDMACH1->CLLI = 0;							//e. linked list is empty
  
	if (trm_num_byt > 16)					   			//e. a packet is too long for FIFO 
	 {		
		LPC_GPDMACH1->CControl |= 16; 		   			//e. set length of first packet part
		LPC_GPDMACH1->CLLI = (uint32_t)&LLI0_TypeDef;	//e. initialize chain for other parts transmitting
	 }
	else	 
	   LPC_GPDMACH1->CControl |= trm_num_byt; 

	LPC_GPDMACH2->CControl |= 1;   							//e. set 1 transfert for enable signal   
#if defined UART1TEST
	LPC_UART1->TER = 0;  						//e. disable data output to UART1
#endif
   if (Device_Mode < 4)								 //e. work with internal latch
   {						 	
		LPC_TIM0->TCR = 1;							//e. start timer		
//-------------------debug-----------------------------------------
		LPC_GPIO2->FIOSET |= 8;				//turn on RS-422 driver 
//-------------------debug-----------------------------------------
 
  	LPC_GPDMACH1->CConfig |=  DMAChannelEn;				    //e. DMA for UART transmition
		//LPC_GPIO1->FIOSET = (0x1<<30);
		 
   }

   LPC_GPDMACH2->CConfig |=  DMAChannelEn;                   //e. DMA for enable signal 	  	                          	   
	return;	
}	  
/******************************************************************************
** Function name:		DMA_Init
**
** Descriptions:		
**
** parameters:			
** Returned value:		
** 
******************************************************************************/
void DMA_Init( void )
{
  /* Enable CLOCK into GPDMA controller */
  LPC_SC->PCONP |= GPDMA_POWER_ON;

  /* Select primary function(UART0/1/2/3) in DMA channels,
  secondary is timer 0/1/2/3. */
#if defined UART1TEST
  LPC_SC->DMAREQSEL = 3;
#endif
  //LPC_GPDMA->Sync = (0x1<<DMA_UART0_RX)|(0x1<<DMA_UART1_TX);														//synchronization logic is enabled by default
  LPC_GPDMA->Config = DMA_ControllerEn | DMA_AHB_Little;
  while ( !(LPC_GPDMA->Config & DMA_ControllerEn) ); //wait until DMA_Controller  switched on
  
  NVIC_DisableIRQ(DMA_IRQn);
  return;
}

/******************************************************************************
** Function name:		UARTInit
**
** Descriptions:		Initialisation of UART on 38400 baud
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void UARTInit(void)
{
  uint32_t Fdiv;
  uint32_t pclk;
#if !defined UART1TEST
  uint32_t baudrate = 38400;
#else
  uint32_t baudrate = 38400;
#endif
    LPC_SC->PCONP |= (1<<3);	
   
    LPC_PINCON->PINSEL0 |=  0x00000050;            
            
		pclk = SystemCoreClock/4;

    LPC_UART0->LCR  = word_length_8 |one_stop_bit |no_parity |back_trans_dis |DLAB_access;                     
    Fdiv = (pclk / 16) / baudrate;           
    LPC_UART0->DLM  = Fdiv / 256;
    LPC_UART0->DLL  = Fdiv % 256; 
    LPC_UART0->LCR  &= ~DLAB_access;	                      
    LPC_UART0->FCR  = TX_FIFO_Reset |RX_FIFO_Reset |FIFOs_En |RX_TrigLvl_14;	//0x06;
	LPC_UART0->IER = 0;//RBR_IntEnabl;

	LPC_UART0->FCR |= 0x08;  				//e. DMA mode select 
	//+++++++++++++++++++++++enable signal initialization++++++++++++++++++++++++++
    LPC_PINCON->PINSEL1 &= ~0x0000C000;	//e. select P0.23 as general purpose
	LPC_GPIO0->FIODIR |= 0x00800000;	//e. P0.23 is output 
//	LPC_GPIO0->FIOMASK |= 0x007F0000;	//e. P0.16..P0.22 is not changed by FIOSET writing 
	LPC_GPIO0->FIOCLR |= 0x00800000;	// e. clear P0.23

  return; 
}

void UART1_Init(void)
{
  uint32_t Fdiv;
  uint32_t pclk;
#if !defined UART1TEST
  uint32_t baudrate = 256000;
  #else
  uint32_t baudrate = 38400;
#endif
    LPC_SC->PCONP |= (1<<4);	 //switch on UART1
   
    LPC_PINCON->PINSEL4 |=  (2<<0)|(2<<2)|(2<<10)|(2<<14); //P2.0, P2.1, P2.5, P2.7          
            
		pclk = SystemCoreClock/4;

    LPC_UART1->LCR  = word_length_8 |one_stop_bit |no_parity |back_trans_dis |DLAB_access;                     
    Fdiv = (pclk / 16) / baudrate;           
    LPC_UART1->DLM  = Fdiv / 256;
    LPC_UART1->DLL  = Fdiv % 256; 
    LPC_UART1->LCR  &= ~DLAB_access;	                      
    LPC_UART1->FCR  = TX_FIFO_Reset |RX_FIFO_Reset |FIFOs_En |RX_TrigLvl_14;	//0x06;

	LPC_UART1->RS485CTRL = (1<<5); //(1<<4);

	LPC_UART1->IER = 0;//RBR_IntEnabl;

	LPC_UART1->FCR |= 0x08;  				//e. DMA mode select 
  return; 
}
//----------------------temp----------------------------
/*int UART0_SendByte (int ucData)
{
//	while (!(LPC_UART1->LSR & 0x20));
    return (LPC_UART0->THR = ucData);
}*/
//----------------------temp----------------------------
int UART1_SendByte (int ucData)
{
//	while (!(LPC_UART1->LSR & 0x20));
    return (LPC_UART1->THR = ucData);
}
/******************************************************************************
** Function name:		UART_SwitchSpeed
**
** Descriptions:		Change UART speed 
**
** parameters:			Demanded speed
** Returned value:		None
** 
******************************************************************************/
void UART_SwitchSpeed(unsigned Speed)
{
  uint32_t Fdiv;
  uint32_t pclk;

  pclk = SystemCoreClock/4;
#if defined  UART1REC
	LPC_UART1->LCR |= DLAB_access;
#else
	LPC_UART0->LCR |= DLAB_access;
#endif
	switch (Speed)
	{
		case Sp38400:
		 Fdiv = (pclk / 16) / 38400; 
		 EnablLength = 3240;
		break;

		case Sp115200:
		 Fdiv = (pclk / 16) /115200; 
		 EnablLength = 1090;
		break;

		case Sp460800:
		 Fdiv = (pclk / 16) / 460800; 		 
		break;

		case Sp921600:
		 Fdiv = (pclk / 16) / 921600; 
		 EnablLength = 140;
		break;

	}
#if defined UART1REC	           
    LPC_UART1->DLM  = Fdiv / 256;
    LPC_UART1->DLL  = Fdiv % 256; 
    LPC_UART1->LCR  &= ~DLAB_access;
#else
	LPC_UART0->DLM  = Fdiv / 256;
    LPC_UART0->DLL  = Fdiv % 256; 
    LPC_UART0->LCR  &= ~DLAB_access;
#endif
}
/******************************************************************************
** Function name:		UART_DMA_Init
**
** Descriptions:		Initialisation of DMA channel  for UART transmitter
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void UART_DMA_Init()
{
//+++++++++++++++++config channel for UART0+++++++++++++++++++++++++++++++++++++++++++++++
	LPC_GPDMACH1->CConfig &=  ~DMAChannelEn;  

	LPC_GPDMA->IntTCClear = DMA1_IntTCClear;
	LPC_GPDMA->IntErrClr = DMA1_IntErrClear; 
	  
	 LPC_GPDMACH1->CSrcAddr = (uint32_t)&trm_buf;
 	 LPC_GPDMACH1->CDestAddr = UART1_DMA_TX_DST;
   LPC_GPDMACH1->CControl = SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;
#if defined UART1TEST
	 LPC_GPDMACH1->CConfig |= MaskTCInt | MaskErrInt | DMA_MEMORY | DstDMA_UART1_TX |(M2P << 11);
#else
	g LPC_GPDMACH1->CConfig |= MaskTCInt | MaskErrInt | DMA_MEMORY | DstDMA_UART0_TX |(M2P << 11);
#endif

	EnablDMA = (LPC_GPDMACH1->CConfig)|DMAChannelEn; //save register content for DMA starting in multidrop mode
//**********for Rate mode output*****************************	
 #if defined UART1TEST 											
	  LLI1_TypeDef[0] = (uint32_t)&trm_buf[32];
		LLI1_TypeDef[1] = UART1_DMA_TX_DST;
		LLI1_TypeDef[2] = 0;
		LLI1_TypeDef[3] = (12 & 0x0FFF) | SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;

	  LLI0_TypeDef[0] = (uint32_t)&trm_buf[16];
		LLI0_TypeDef[1] = UART1_DMA_TX_DST;
		LLI0_TypeDef[2] = (uint32_t)&LLI1_TypeDef;
		LLI0_TypeDef[3] = (16 & 0x0FFF) | SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;
#else
	 	LLI1_TypeDef[0] = (uint32_t)&trm_buf[32];
		LLI1_TypeDef[1] = UART0_DMA_TX_DST;
		LLI1_TypeDef[2] = 0;
		LLI1_TypeDef[3] = (12 & 0x0FFF) | SrcBSize_1 | DstBSize_1 | SrcWidth_8b | DstWidth_8b | SrcInc | DstFixed | TCIntDisabl;

	  LLI0_TypeDef[0] = (uint32_t)&trm_buf[16];
		LLI0_TypeDef[1] = UART0_DMA_TX_DST;
		LLI0_TypeDef[2] = (uint32_t)&LLI1_TypeDef;
		LLI0_TypeDef[3] = (16 & 0x0FFF)|SrcBSize_1 |DstBSize_1 |SrcWidth_8b 
						|DstWidth_8b|SrcInc |DstFixed |TCIntDisabl;
#endif
//++++++++++++++++++++++++++config channel for transmit enable signal+++++++++++++++++++
  LPC_GPDMACH2->CConfig &= ~DMAChannelEn;  

 	LPC_GPDMA->IntTCClear = DMA2_IntTCClear;
	LPC_GPDMA->IntErrClr = DMA2_IntErrClear; 

	LPC_GPDMACH2->CSrcAddr = (uint32_t)&EnablTx; //e.	content of TX UART1 enable register
	LPC_GPDMACH2->CDestAddr = 0x40010030;	   //e.	address of TX UART1 enable register (U1TER)
	  											
	LPC_GPDMACH2->CControl = SrcBSize_4 |DstBSize_4   
		                    |SrcWidth_8b |DstWidth_8b|SrcFixed |DstFixed |TCIntEnabl;

	LPC_GPDMACH2->CConfig |= MaskTCInt |MaskErrInt 
	    				  |SrcDMA_UART0_RX |DstDMA_UART0_RX|(M2P << 11);
	LPC_GPDMACH2->CLLI = 0;								//e. linked list is empty	 

//++++++++++++++++++++++++++config channel for DMA1 enable signal+++++++++++++++++++
#if defined UART1TEST
    LPC_GPDMACH4->CConfig &= ~DMAChannelEn;  

  	LPC_GPDMA->IntTCClear = DMA4_IntTCClear;
	LPC_GPDMA->IntErrClr = DMA4_IntErrClear; 
 
	LPC_GPDMACH4->CSrcAddr = (uint32_t)&EnablDMA; //e.	content of TX UART1 enable register
	LPC_GPDMACH4->CDestAddr = 0x50004130;	   //e.	address of DMA1CConfig register
	  											
	LPC_GPDMACH4->CControl = SrcBSize_4 |DstBSize_4   
		                    |SrcWidth_8b |DstWidth_8b|SrcFixed |DstFixed |TCIntEnabl;

	LPC_GPDMACH4->CConfig |= MaskTCInt |MaskErrInt 
	    				  |SrcDMA_UART0_TX |DstDMA_UART0_TX|(M2P << 11);
	LPC_GPDMACH4->CLLI = 0;								//e. linked list is empty	
#endif									
}
/******************************************************************************
**                            End Of File
******************************************************************************/