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

📄 dsp_modem.c

📁 DSP 5409 plc应用程序,调试通过,是用在电力线通讯上的演示程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================================
// Filename:		dsp_modem.c
//
// Description:		Main loop for ofdm power line modem.
//
// Copyright (C) 2001 - 2003 Texas Instruments Incorporated
// Texas Instruments Proprietary Information
// Use subject to terms and conditions of TI Software License Agreement
//
// Revision History:
//==========================================================================================
#include "intr.h"
#include "ofdm_modem.h"
#include "uart.h"
#include "Flash.h"

//==========================================================================================
// Local function declarations
//==========================================================================================
void InitEverything(void);
void InitVars(void);
u16	 InitHardware(void);
void InitTimer0(void);
u16  ReceivePacket(void);
void TestInterruptFlag(u16 uMarker);
void SetTxBias(u16 uBias);

// Transmitter Amplifier Current Bias Setting Options
#define	TX_BIAS_OFF		3
#define	TX_BIAS_LOW		2
#define	TX_BIAS_MID		1
#define	TX_BIAS_FULL	0
#define	TX_BIAS_ON		TX_BIAS_MID		// Bias setting to enable transmit amplifier (choose from LOW, MID, or FULL)


//==========================================================================================
// Set global vars
//==========================================================================================
u16		packetCntr = 0;

// Local error code definitions.
#define	ERR_RX_FRAME_ALIGN		(0xBBD1)
#define	ERR_RX_PARITY			(0xBADF)
#define ERR_RX_ADDR_MISMATCH	(0x0001)
#define ERR_CMD_BLOCKED			(0x0002)
#define	RX_TIMEOUT				(PACKET_TIME*5)		// About five packet times - used for LED toggling.


//==========================================================================================
// Function:		PulseXF()
//
// Description: 	Pulses the XF pin a desired number of times to aid in debug.  
//
// Revision History:
//==========================================================================================
void PulseXF(u16 uN)
{
	u16 i;		// Loop counter

	for (i= 0; i<uN; i++)
	{
		SetXF();				// Turn on XF flag for debug
		DelayNus(1);
		ClearXF();
		DelayNus(1);
	}
	DelayNus(3);

	return;
}


//==========================================================================================
// Function:		main()
//
// Description: 	Main function.  
//					Used for testing the OFDM encode/decode functions and the AFE hardware.
//					Eventually this will be replaced with a fuller version with task 
//					swapping.
//					Initializes variables and hardware in idle transmission mode.
//					Constructs and transmits a data packet and returns to idle.
//					Captures the transmitted waveform and decodes it.
//
// Revision History:
//==========================================================================================
void main()
{ 
	volatile u16	BailOut = 0;

//================ CONFIGURE THE SYSTEM ==================================
	INTR_GLOBAL_DISABLE();	// Disable Global Interrupts (if they were enabled)

	InitEverything();		// Set up DSP memory config registers, program variables,
							// MCBSP ports and DMA engines, and periodic timer.
							// Enable interrupts.

	SetXF();				// Turn on XF flag for debug

	//====== MAIN LOOP ========
	BailOut = 0;
		INTR_GLOBAL_DISABLE();	//###TEMP Disable Global Interrupts (if they were enabled)
	while(BailOut == 0)		// Loop forever, unless BailOut is changed using an emulator
	{
		PulseXF(2);			//### Pulse XF line to aid debug

		TurnLEDsOff(LED_LOOP_ACTIVE | LED_RX_AGC_HOLD | LED_RX_FRAME_ALIGN | LED_RX_BUFF_ERR | LED_RX_SEARCH );// Turn off bottom 5 LEDs	
		TurnLEDsOn(LED_LOOP_ACTIVE);	// Turn on green LED0	
		DebugDelay();		// Flush C54x if in debug mode.
		ClearXF();			//### Turn on XF flag for debug

		CheckPLC();			// Monitors for PL activity.
		
		// If we're waiting for the last bit of a RS485 packet to go out, don't start receiving
		// a PLC packet.  The outgoing RS485 bit will only take about 10 usec which won't affect
		// the PLC, but if we start receiving a PLC packet, we'll miss the e-meter response on
		// the 485 since we'll still be in 485 talk mode.
		// This can also be set through the Host using the SetParm command.
		if (uHoldOffPLC == 0)
		{
			ReceivePLC();		// Check for and handle incoming PL data.
		}

		ReceiveUART();		// Check for and handle incoming UART data.

		SendPLC();			// Manage outgoing PL data.
		
		SendUART();			// Manage outgoing UART data.

		BERTest();			// Handles BER testing

		AutoPoll();			// Handles periodic idle polling of SLAVE when appropriate.

		CheckTimeouts();	// See if we timed out while waiting for data.

		CheckFlash();		// execute current flash state machine state and return

		if(uSlaveFound == 0)	// Has a closest slave been identified yet?
		{
			CheckForClosestSlave();
		}
		else if(uFindSlaves == 1)	// Command to find slaves is running.
		{
			FindSlaves();
		}
	}

	DebugDelay();				// Flush C54x if in debug mode.

	//This is for debug use only:  Halt the MCBSP so we don't lose the data in the receive buffer.
	// Shut off frame sync generation (FS)
	MCBSP_SUBREG_BITWRITE(AFE_MCBSP, SPCR2_SUBADDR, FRST, FRST_SZ, 0);
	DebugDelay();				// Flush C54x if in debug mode.
}	
//=============================== END OF MAIN()  ===========================================


//==========================================================================================
// Function:		CheckPLC()		
//
// Description:		This function now is used to turn off the parity error and packet good
//					LEDs and to toggle the XF pin.
//
//					It also checks to see if Global Interrupts have been disabled during
//					the loop and re-enables them.  (This shouldn't happen.  It looks like
//					it is related to the reading of the DMA source pointer...)
//
// Revision History:
//==========================================================================================
void CheckPLC()
{
	volatile u16	ST1Shadow;			

	SetXF();							// Turn on XF flag for debug
	DebugDelay();						// Flush C54x if in debug mode.

	ST1Shadow = ST1 & 0x0800; 
	
	if (ST1Shadow != 0)
	{
		PostErrorCode(0xBAE5, "CheckPLC", "dsp_modem.c", "Re-enabling Global interrupts");
		#if SAVETRACE == TRUE
		{
			volatile u16	uRxDMA;
			uRxDMA = (u16)ReadRxDMAPointer();	// Read DMA destination pointer in RxBuffer
			SaveTraceData(0xBAE5);				//!!!DEBUG  Put a marker in the trace buffer
			SaveTraceData((u16)recSignal); 		//!!!DEBUG  Put a marker in the trace buffer
			SaveTraceData(uRxDMA);				//!!!DEBUG  Put a marker in the trace buffer
		}
		#endif
		INTR_GLOBAL_ENABLE();		// Enable Global Interrupts (not supposed to be disabled, but turn them on again anyway
		DebugDelay();				// Flush C54x if in debug mode.
		DebugDelay();				// Flush C54x if in debug mode.
	}

	DebugDelay();				// Flush C54x if in debug mode.
	ClearXF();					// Turn off XF flag for debug

	if (ulLastRxCounter > RX_TIMEOUT)	// Turn off Parity Error and Good packet LEDs after RX_TIMEOUT
	{
		ulLastRxCounter = 0;				// Reset the Rx timeout counter
		TurnLEDsOff(LED_RX_PARITY_ERR);		// Turn off red LED7
		TurnLEDsOff(LED_RX_PACKET_GOOD);  	// Turn off green LED6	
	}			

	DebugDelay();				// Flush C54x if in debug mode.
}


//==========================================================================================
// Function:		ReceivePLC()		
//
// Description:		Check for and handle incoming PL data.
//
// Revision History:
//==========================================================================================
void ReceivePLC(void)
{
	u16		uStatus = ~SUCCESS;
	// Next declaration needed if the LCD update code below is restored.
	// u16		emeterMsgString[20];	
	
	if(agcState == AgcHold)		// Data is coming in via PLC
	{
		ulLastRxCounter = 0;			// Reset the Rx timeout counter
		uStatus = ReceivePacket();		// Data will be read into rxUserDataCopy[]

		if (uStatus == SUCCESS) 	// Good packet addressed to me was received.
		{
			// MASTER was expecting SLAVE RESPONSE
			if(uPlcState == PLC_RECEIVE_RESPONSE)	
			{
				// Send received PLC data on to host.
				WriteUART(UART_TARGET_HOST, uHostResponseLength, &rxUserDataCopy[uHostResponseStart] ); // count, pointer
				uPlcState = PLC_IGNORE;
				ulAutoPollCounter = 0L;
				uAutoPollPause=0;		// Release AutoPoll.
			}
		
			// MASTER was expecting SLAVE RESPONSE to periodic polling.
			else if(uPlcState == PLC_RECEIVE_POLLING)
			{
				uPlcState = PLC_IGNORE;
			}

			// MASTER is looking for closest slave (and found one).
			else if(uPlcState == PLC_FIND_CLOSEST_SLAVE)
			{
				ulClosestSlaveAddr = (u32)rxUserDataCopy[2]*65536L + (u32)rxUserDataCopy[3];
				uSlaveFound = 1;
				uPlcState = PLC_IGNORE;
				uUartState =  UART_RECEIVE_COMMAND;

				// May want to do something here in the future, so don't delete...
				// !!!!!	// Update LCD display
				// !!!!!	emeterMsgString[0] = (u16) 'W';		// Write command.
				// !!!!!	emeterMsgString[1] = (u16) 'R';
				// !!!!!	emeterMsgString[2] = (u16) 'e';
				// !!!!!	emeterMsgString[3] = (u16) 'a';
				// !!!!!	emeterMsgString[4] = (u16) 'd';		// "Ready"
				// !!!!!	emeterMsgString[5] = (u16) 'y';
				// !!!!!	emeterMsgString[6] = (u16) ' ';
				// !!!!!	emeterMsgString[7] = (u16) ' ';
				// !!!!!	emeterMsgString[8] = (u16) 0xd;		// \r
				// !!!!!	emeterMsgString[9] = 0;				// String terminator.
				// !!!!!	WriteUARTString(emeterMsgString);
				// !!!!!	uUartState = UART_RECEIVE_COMMAND;
				// !!!!!	uAckAfter485 = 0;
				// !!!!!
				// !!!!!	// Update Slave LCD display.
				// !!!!!	memset(txUserDataArray, 0, DATA_BUFFER_LEN*sizeof(txUserDataArray[0]));	
				// !!!!!	*(u32*)&txUserDataArray[0] = ulClosestSlaveAddr;	// Destination address default
				// !!!!!	*(u32*)&txUserDataArray[2] = ulMyAddr;
				// !!!!!	txUserDataArray[4] = 0x10;			// Command number = slave emeter command.
				// !!!!!	txUserDataArray[5] = (((u16) 'W')<<8) + ((u16) 'R');		// Write command.
				// !!!!!	txUserDataArray[6] = (((u16) 'e')<<8) + ((u16) 'a');
				// !!!!!	txUserDataArray[7] = (((u16) 'd')<<8) + ((u16) 'y');
				// !!!!!	txUserDataArray[8] = (((u16) 0xd)<<8) + 0;				// \r, string terminator
				// !!!!!	uTransmitPacketReady = 1;			// Send completed command to the SLAVE.
				// !!!!!	uPlcState = PLC_IGNORE;				// Don't care about response
			}

			// MASTER is looking for all slaves (and found one).
			else if(uPlcState == PLC_FIND_ALL_SLAVES)
			{
				ulFindSlaveAddr = (u32)rxUserDataCopy[2]*65536L + (u32)rxUserDataCopy[3];
				uFindSlaves = 0;		// Stop looking.
				uPlcState = PLC_IGNORE;
				ulAutoPollCounter = 0L;
				uAutoPollPause = 0;
				WriteUART(UART_TARGET_HOST, 2, (u16*) &ulFindSlaveAddr);

				// If we'd never found a slave before, might as well initialize this in case we
				// get commands to slave 0 (closest).
				if (ulClosestSlaveAddr == 0)
				{
					ulClosestSlaveAddr = ulFindSlaveAddr;
				}
			}
														
			// SLAVE was waiting for COMMAND
			else if(uPlcState == PLC_RECEIVE_COMMAND)	
			{
				// Keep most recent received address to use for MASTER addr in BER
				ulMasterAddr = (u32)rxUserDataCopy[2]*65536 + (u32)rxUserDataCopy[3];	
													
				ProcessSlaveCommand();
			}
		}
	}
}


//==========================================================================================
// Function:		ReceiveUART()	
//
// Description:		Check for and handle incoming UART data.
//
// Revision History:
// 06/06/03 EGO		New function.
//==========================================================================================
void ReceiveUART(void)
{

⌨️ 快捷键说明

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