⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phy_layer.c

📁 ST7540 Demo 下位机C程序
💻 C
字号:
/*********************************************************************************
*                 ST 7538 DEMOBOARD SOFTWARE 	  Phy_Layer.c                       *
*                                                                                 *
*                 SPI uc<->modem  functions                          V1.2         *
***********************************************************************************/


#include "global.h"

#pragma DATA_SEG APP_RAM

BYTE		SPI_Bits;			// How many BITS have been sent/received
BYTE		SPI_RxIn;			// How many BYTES have been received in BUFFER
BYTE		SPI_RxOut;			// How many BYTES received in BUFFER have been setnt to PC interface
BYTE		SPI_TxOut;			// How many BYTES have been TXED from BUFFER
BYTE		SPI_TxIn;			// How many BYTES to TX into the BUFFER
BYTE		SPI_DR;				// the SW SPI Data register
BYTE		SPI_LoopStart;			// start of packet in looping mode
BYTE		Nb_byte_to_receive;            	//In synchro mode, the total nb of byte received in the frame 
BYTE		Nb_byte_to_receive_rest;	//In synhro mode, during rx of data, the resting number of byte to receive
WORD		Header;
BYTE		Loop;				//number of Tx frame to repeat
WORD		Mask;
WORD		Head_Reg;

#pragma CODE_SEG APPLI_CODE

/**********************************************************************************
* SPI_Init function: HW initialization
**********************************************************************************/
void SPI_Init(void)
{
	
	SPI_Flags = 0;
	Repeated_Mode = REPEAT_MODE_OFF;
	Repeating_Number = 0;
	
	// Configuration of TX SPI I/O 
	TX_SPI_DIR  |= (TX_DATA_MASK);		// in output push pull set to 0
	TX_SPI_OP_R |= (TX_DATA_MASK);				                            
	TX_SPI_PORT &=~(TX_DATA_MASK);
	// Configuration of RX SPI I/O 
	RX_SPI_DIR  &= ~(RX_DATA_MASK);		// in input floating
	RX_SPI_OP_R &= ~(RX_DATA_MASK);		                            
	// Configuration of CLRT
	CLRT_DIR    &= ~(CLRT_MASK);		// in input  floating, but not yet 
	CLRT_OP_R   &= ~(CLRT_MASK);		// in pull up interrupt
	MISCR1 = MISCR1 & 0x3F;
	MISCR1 = MISCR1 | 0x40;				// CLRT int on rising edge 
	//RX/TX_
	RX_TX_DIR   |=   (RX_TX_MASK);		// RXTX in output push pull in RX mode by default. 
	RX_TX_OP_R  |=   (RX_TX_MASK);
	RX_TX_PORT  |=   (RX_TX_MASK);
	//REG/DATA_	
	REG_DTA_DIR |=   REG_DTA_MASK;		// in output push pull in DATA mode
	REG_DTA_OP_R|=   REG_DTA_MASK;
	REG_DTA_PORT&= ~(REG_DTA_MASK);
	//Carrier/Preamble detection
	CD_PD_DIR   &= ~(CD_PD_MASK);		// in input floating
	CD_PD_OP_R  &= ~(CD_PD_MASK);
	//Configure REG_OK pin
	REG_OK_DIR  &= ~(REG_OK_MASK);		// in input floating
	//Configure TOUT pin (time out)
	TIMEOUT_DIR &= ~(TIMEOUT_MASK);	// in input floating
	TIMEOUT_OP_R&= ~(TIMEOUT_MASK);
	//BAND in USED	
	BANDUSED_DIR  &= ~(BANDUSED_MASK);	// in input floating
	//BANDUSED_OP_R &= ~(BANDUSED_MASK);
	// Zero Crossing detection signal
	XCROSS_DIR  &= ~(XCROSS_MASK);		// in input floating
	XCROSS_OP_R &= ~(XCROSS_MASK);
	
	ST7538_CR=0x00;				// initialization of CR
	CLRT_OP_R |= CLRT_MASK; //always active
}

/**********************************************************************************
* SPI_Enable function: enable SPI interrupt on falling edge of CLR/T pin
**********************************************************************************/
void SPI_Enable(void)
{

	if(SPI_Flags&SPI_IN_TX_MASK) {
		SPI_TxOut = 0;
		SPI_DR = SPI_Buffer[SPI_TxOut];
		if(SPI_DR&0x80)
			TX_SPI_PORT |= TX_DATA_MASK;
		else
			TX_SPI_PORT &= ~(TX_DATA_MASK);
		SPI_DR <<= 1;
		SPI_Bits = 1;
	}
	else {
		SPI_Bits  = 0;
		SPI_RxIn  = 0;
		SPI_DR = 0;
	}

	CLRT_OP_R |= CLRT_MASK;
}

/**********************************************************************************
* SPI_Disable function: disable SPI interrupt 
**********************************************************************************/
void SPI_Disable(void)
{
  //CLRT_OP_R    &= ~(CLRT_MASK);
  SPI_Flags    &= ~(SPI_IN_RX_MASK|SPI_IN_TX_MASK|SPI_REG_MASK|SPI_SYNCHRO_MASK|SPI_RXED_SYN_MASK);
	RX_TX_PORT   |= RX_TX_MASK;
	REG_DTA_PORT &= ~(REG_DTA_MASK);
  TX_SPI_PORT &= ~TX_DATA_MASK;
}

/**********************************************************************************
* SPI_Interrupt function: SPI interrupt routine 
**********************************************************************************/
#pragma TRAP_PROC //SAVE_REGS
void SPI_Interrupt(void)
{
  
//	const static char Byte_Size = 8;  //used for transmit/receive a number of bit != 8

	// RX MODE
	if(SPI_Flags&SPI_IN_RX_MASK) {
		SPI_DR = SPI_DR << 1;
		Head_Reg = Head_Reg << 1;
		if(RX_SPI_PORT&RX_DATA_MASK) {
			SPI_DR |= 0x01;
			Head_Reg |= 0x01;
		}
		else {
			SPI_DR &= 0xFE;
			Head_Reg &= 0xFFFE;
		}
		if(SPI_Bits<15)
			SPI_Bits++;
		// RX Synchro Mode
		if((SPI_Flags&SPI_RXED_SYN_MASK)&&!(SPI_Flags&SPI_SYNCHRO_MASK)) {
			// Waiting for synchronization
			if(SPI_Bits<15)
				return;
		    if(((Head_Reg^Header)&Mask)==0) {	// Synchronized!
				SPI_Flags = SPI_Flags | SPI_SYNCHRO_MASK;
				SPI_Bits = 0;
				SPI_DR = 0;
    		Nb_byte_to_receive_rest = Nb_byte_to_receive;
			}
		}
		// Reception enabled (synchronized or synchronization not required)
		else {
			if(SPI_Bits<8) {
				return;
			}
			
			//if((SPI_Flags&SPI_REG_MASK)||(PING_Status==PS_WAIT)) { 
			 // DI;
			//	SPI_Buffer[SPI_RxIn++] = SPI_DR;
			//	SPI_RxIn &= SPI_BUFFER_MASK;
			//	EI;
			//}
			//else {
			DI;
			SPI_Buffer[SPI_RxIn] = SPI_DR;
			SPI_RxIn = SPI_RxIn + 1;
			SPI_RxIn &= SPI_BUFFER_MASK;
		  EI;
			//}
			SPI_DR = 0;
			SPI_Bits = 0;
			if(SPI_Flags&SPI_RXED_SYN_MASK) {
				if(--Nb_byte_to_receive_rest==0) {
				  DI;
					SPI_Flags &= ~SPI_SYNCHRO_MASK;
					Head_Reg = 0;
					SPI_Bits = 0;
					if (PING_Status==PS_WAIT)
					{
					  PING_Flags |=PF_RECV;
					  SPI_RxIn = 0;
						SPI_RxOut = 0;
					}  
					EI;
				}

			}
		}
	}
	// TX_MODE
	else if(SPI_Flags&SPI_IN_TX_MASK) {
		if(SPI_Bits<8) {
			if(SPI_DR&0x80)
				TX_SPI_PORT |= TX_DATA_MASK;
			else
				TX_SPI_PORT &= ~(TX_DATA_MASK);
			SPI_DR = SPI_DR << 1;
			SPI_Bits++;			
		}
		else {
			if(SPI_TxOut!=SPI_TxIn) {
				SPI_Bits = 0;
			  
				SPI_TxOut = (SPI_TxOut+1)&(SPI_BUFFER_MASK);
				SPI_DR = SPI_Buffer[SPI_TxOut];
				
				if(SPI_DR&0x80)
					TX_SPI_PORT |= TX_DATA_MASK;
				else
					TX_SPI_PORT &= ~(TX_DATA_MASK);
				SPI_DR = SPI_DR << 1;
				SPI_Bits++;			
			}
			else {
				if(!(SPI_Flags&SPI_LOOP_MASK)) {
					SPI_Disable();
				}
				else {
					SPI_TxOut = 0;
					SPI_Bits  = 0;
					
					SPI_DR = SPI_Buffer[SPI_TxOut];
					
					if(SPI_DR&0x80)
						TX_SPI_PORT |= TX_DATA_MASK;
					else
						TX_SPI_PORT &= ~(TX_DATA_MASK);
					SPI_DR = SPI_DR << 1;
					SPI_Bits++;			
				}
			}
		}

	}
}

/**********************************************************************************
* GetControlRegister function: get always 48 bit and put them on RS-232 buffer.
* If lsbits (from 24 to 0 bits )are all "0" or "1" invert three upper bytes with three
* lower bytes in order to have always in last positions of RS-232 buffer [4,5,6] the CR
* bits from 24 to 0.
**********************************************************************************/
BYTE GetControlRegister(unsigned char *CTRL_REG)
{
	unsigned char tim;
	
	// Waits for CLR/T low
  
	
	SPI_Disable();
	
	DI;
	MISCR1 = MISCR1 & 0x3F;		//rising edge
	MISCR1 = MISCR1 | 0x40;
	EI;
	
	tim = TIMEOUT_Open(2);
	while(!TIMEOUT_Expired(tim)) {
		if(!(CLRT_PORT&CLRT_MASK))
			break;
		WatchDogRefresh();
	}
	TIMEOUT_Close(tim);
	
	tim = TIMEOUT_Open(100);

	// Select Lines
	RX_TX_PORT |= (RX_TX_MASK);
	REG_DTA_PORT |= REG_DTA_MASK;
	
	SPI_Flags |= (SPI_IN_RX_MASK|SPI_REG_MASK);
	SPI_RxIn = 0;
	

	
	SPI_Enable();

	// Waits for 6 bytes read
	while(SPI_RxIn<6) {
		if(TIMEOUT_Expired(tim))
		{
  	  SPI_Disable();
  	  TIMEOUT_Close(tim);
  	  REG_DTA_PORT &= ~REG_DTA_MASK;  
  	  return 1;
	  }		
		WatchDogRefresh();
	}
	
	SPI_Disable();
	REG_DTA_PORT &= ~REG_DTA_MASK;

  DI;	
	if (((SPI_Buffer[3]==0xFF)&&(SPI_Buffer[4]==0xFF)&&(SPI_Buffer[5]==0xFF))
	     ||((SPI_Buffer[3]==0x00)&&(SPI_Buffer[4]==0x00)&&(SPI_Buffer[5]==0x00))) {
		// 24 bit register
		memcpy(((BYTE *)&ST7538_CR)+1,SPI_Buffer,3);
		memcpy(CTRL_REG,SPI_Buffer+3,3);
		memcpy(CTRL_REG+3,SPI_Buffer,3);
		(*(CTRL_REG + 6)) = 0x00;	 //information byte
	}
	else {
		// 48 bit register
		memcpy(((BYTE*)&ST7538_CR)+1,SPI_Buffer+3,3);
		memcpy(CTRL_REG,SPI_Buffer,3);
		memcpy(CTRL_REG+3,SPI_Buffer+3,3);	
		(*(CTRL_REG + 6)) = 0xFF; //information byte
	}
	EI;
	TIMEOUT_Close(tim);
	return 0;
}

/**********************************************************************************
* SetControlRegister function: write 48 CR
**********************************************************************************/
BYTE SetControlRegister(unsigned char *CTRL_Reg)
{
	unsigned char tim;

	SPI_Disable();
	
	DI;
	MISCR1 = MISCR1 & 0x3F;		//falling edge
	MISCR1 = MISCR1 | 0x80;
	
		
	memcpy(SPI_Buffer,CTRL_Reg,6);	 //put all bytes on SPI buffer
	memcpy(((BYTE*)&ST7538_CR)+1,CTRL_Reg+3,3);		//update CR	 (only bits from 24 to 0)
  EI;


	// Waits for CLR/T low
	tim = TIMEOUT_Open(2);
	while(!TIMEOUT_Expired(tim)) {
		if(!(CLRT_PORT&CLRT_MASK))
			break;
		WatchDogRefresh();
	}
	TIMEOUT_Close(tim);
	
	tim = TIMEOUT_Open(100);
	// Select Lines
	RX_TX_PORT &= ~(RX_TX_MASK);
	REG_DTA_PORT |= REG_DTA_MASK;
	SPI_Flags |= (SPI_IN_TX_MASK|SPI_REG_MASK);
	SPI_TxIn = 6;
	


	SPI_Enable();


	while(SPI_TxOut!=SPI_TxIn) {
		if(TIMEOUT_Expired(tim))
		{
  	  SPI_Disable();
  	  TIMEOUT_Close(tim);
  	  return 1;
	  }		
		WatchDogRefresh();
	}
	SPI_Disable();
	TIMEOUT_Close(tim);
	return 0;
}

/**********************************************************************************
* SPI_OnRx function: return 1 if  SPI is running in RX mode, 0 otherwise
**********************************************************************************/
unsigned char SPI_OnRx(void)
{
	return ((SPI_Flags&SPI_IN_RX_MASK)&&!(SPI_Flags&SPI_REG_MASK));
}
/**********************************************************************************
* SPI_OnTx function: return 1 if SPI is running in TX mode, 0 otherwise
**********************************************************************************/
unsigned char SPI_OnTx(void)
{
	return (SPI_Flags&SPI_IN_TX_MASK);
}
/**********************************************************************************
* SPI_OnRun function: return 1 if SPI is running in RX or Tx mode, 0 otherwise
**********************************************************************************/
unsigned char SPI_OnRun(void)
{
	return (SPI_Flags&(SPI_IN_RX_MASK|SPI_IN_TX_MASK));
}
/**********************************************************************************
* Tx_Data function: copy data to sent in SPI buffer and set TX flags depending of type of Tx 
**********************************************************************************/
void Tx_Data(unsigned char msg_rep, unsigned char msg_len, char *msg)
{
	DI;
	memcpy(SPI_Buffer,msg,msg_len);
	EI;
	
	SPI_Flags    &= ~(SPI_LOOP_MASK);
	Repeated_Mode = REPEAT_MODE_OFF;

	if(msg_rep==0) {	// Continuous Transmission
		SPI_Flags    |= SPI_LOOP_MASK;
	}
	else {				// Repeated Transmission
		if(msg_rep>1) {
			Repeated_Mode    = REPEAT_MODE_ON;
			Repeating_Number = msg_rep;
			refresh_200mS_Delay();
		}
	}
	

	DI;	
	MISCR1 = MISCR1 & 0x3F;		//falling edge
	MISCR1 = MISCR1 | 0x80;
	EI;
	
	SPI_TxIn     = msg_len-1;
	SPI_Flags   |= SPI_IN_TX_MASK;
	REG_DTA_PORT &= ~(REG_DTA_MASK);
	RX_TX_PORT   &= ~(RX_TX_MASK);


	SPI_Enable();
}
/**********************************************************************************
* Rx_Data function: set RX flags depending of type of Rx 
**********************************************************************************/
void Rx_Data(unsigned char Rx_Type,unsigned short Rx_Head,
             unsigned short Rx_Mask,unsigned char Rx_Len)
{
	SPI_Flags &= ~(SPI_RXED_SYN_MASK);

  DI;
  MISCR1 = MISCR1 & 0x3F;		//rising edge
  MISCR1 = MISCR1 | 0x40;
  EI;

	switch (Rx_Type) {
	case RX_SYN_TXDH:
	  TX_SPI_PORT |= TX_DATA_MASK;
	case RX_SYN:
		Header = Rx_Head;
		Mask   = Rx_Mask;
		Nb_byte_to_receive = Rx_Len;
		SPI_Flags |= SPI_RXED_SYN_MASK;
	case RX_TXDH:
		if(Rx_Type==RX_TXDH)
			TX_SPI_PORT |= TX_DATA_MASK;
	case RX_NO_SYN:
		SPI_Flags |= SPI_IN_RX_MASK;
		RX_TX_PORT |= RX_TX_MASK;
		REG_DTA_PORT &= ~(REG_DTA_MASK);
		

	
		SPI_Enable();
		break;
	}
}
/**********************************************************************************
* RepMode_Analyze function: manages repeated Tx mode (every 200ms) 
**********************************************************************************/
void RepMode_Analyze(void)
{
	if(Repeating_Number>1) {
		if(_200mS_Delay_Elapsed()&&!SPI_OnRun()) {
		  DI;
			Repeating_Number--;
			SPI_TxOut     = 0;
			SPI_Flags    |= SPI_IN_TX_MASK;
			RX_TX_PORT   &= ~(RX_TX_MASK);
			REG_DTA_PORT &= ~(REG_DTA_MASK);
			refresh_200mS_Delay();
			MISCR1 = MISCR1 & 0x3F;		//falling edge
    	MISCR1 = MISCR1 | 0x80;
    	EI;
			SPI_Enable();
		}
	}
	else {
	  Repeated_Mode = REPEAT_MODE_OFF;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -