📄 dsp_modem.c
字号:
//==========================================================================================
// 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 + -