📄 dsp_modem.c
字号:
DebugDelay(); // Flush C54x if in debug mode.
SNRflag = SNRflagBackup; // Restore the SNRflag
TurnLEDsOff(LED_TX_PACKET); // Turn off green Tx LED1
return;
}
//==========================================================================================
// Function: ReceivePacket()
//
// Description: This function receives a packet from the power-line communication
// interface, decodes it, checks for errors, and stores the resulting
// message in rxUserDataArray, then copies into rxUserDataCopy to
// prevent overwriting.
//
// Revision History:
//==========================================================================================
u16 ReceivePacket(void)
{
u16 errCount = 0;
volatile i16 uNonZeroBits = 0; // Count of non-zero bits in received message
volatile u16 uRxDMA;
u16 uStatus;
TurnLEDsOn(LED_RX_AGC_HOLD); //Turn on yellow LED6
#if SAVETRACE == TRUE
uRxDMA = (u16)ReadRxDMAPointer(); // Read DMA destination pointer in RxBuffer
SaveTraceData(0xACCA); //!!!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
//====================================================================
// read data and do detection
//=====================================================================
recSignal = frameAlign(phaseEqArray, recSignal );
DebugDelay(); // Flush C54x if in debug mode.
if (frameAligned == 0)
{
agcState = AgcIdle;
preambleDetCount = 0; // start over
uStatus = ERR_RX_FRAME_ALIGN;
}
else // Preamble Frame Align successful. Read the data frames.
{
TurnLEDsOn(LED_RX_FRAME_ALIGN); //Turn on yellow LED5
packetCntr++;
ulLastRxCounter = 0; // Reset the Rx timeout counter
#if SAVETRACE == TRUE
SaveTraceData(0xACCB); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)ulLastRxCounter);//!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)0000); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(0xACCC); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(packetCntr); //!!!DEBUG Put a marker in the trace buffer
#endif
DebugDelay(); // Flush C54x if in debug mode.
errCount = readDataFrames(rxUserDataArray, recSignal, phaseEqArray );
if( errCount != 0 )
{
uStatus = ERR_RX_PARITY; // Parity Error
DebugDelay(); // Flush C54x if in debug mode.
PostErrorCode(0xBADF, "main", "dsp_modem.c", "Parity errors");
TurnLEDsOn(LED_RX_PARITY_ERR); // Turn on red LED3
TurnLEDsOff(LED_RX_PACKET_GOOD);// Turn off green LED4
// Increment BER error counter for parity errors
if(uBerTestInProgress == 1)
{
uBerErrorCounter++;
}
#if SAVETRACE == TRUE
uNonZeroBits = countErrors(rxUserDataArray);
DebugDelay(); // Flush C54x if in debug mode.
SaveTraceData(0xBADF); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(uNonZeroBits); //!!!DEBUG Put a marker in the trace buffer
#endif
#if SAVESYMBOLS == TRUE
{
u16 n; // append the freqEq coeficients to the tracebuffer
iCplx *feqPtr = phaseEqArray;
for(n = 0; n < CARRIER_LEN; n++ )
{
SaveTraceData((u16)(feqPtr->re));
SaveTraceData((u16)(feqPtr->im));
feqPtr++;
}
uTraceEnable = FALSE; // halt saving to tracebuffer
}
#endif
DebugDelay(); // Flush C54x if in debug mode.
DebugDelay(); // Flush C54x if in debug mode.
}
else
{
// Good packet received. Turn off parity error LED.
DebugDelay(); // Flush C54x if in debug mode.
PostErrorCode(0xBAD0, "main", "dsp_modem.c", "Good Packet Received!");
TurnLEDsOff(LED_RX_PARITY_ERR); // Turn off red LED3
TurnLEDsOn(LED_RX_PACKET_GOOD); //Turn on green LED4
#if SAVETRACE == TRUE
SaveTraceData(0xBAD0); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(errCount); //!!!DEBUG Put a marker in the trace buffer
#endif
// Only overwrite rxUserDataCopy if the destination adddress matches myAddr.
if( (*(u32*)&rxUserDataArray[0] == ulMyAddr) // Is this packet addressed to me?
|| ( (*(u32*)&rxUserDataArray[0] == 1) && (uBoard == BOARD_SLAVE) ) // Check for slave broadcast.
|| ( (*(u32*)&rxUserDataArray[0] == 2) && (uBoard == BOARD_MASTER) ) ) // Check for master broadcast.
{
// Check if we're already processing a command. If command blocking is enabled
// do not receive another packet!
// This test was added for the case when another MASTER on the same powerline
// comes up and starts trying to find slaves. It may eventually issue a
// find slave command to our slave - which looks like a valid command so
// without this test we'll overwrite rxUserDataCopy, which results in the
// response to the currently active command being sent to the wrong MASTER.
if((uBoard==BOARD_SLAVE) && (uCommandBlock==1))
{
uStatus = ERR_CMD_BLOCKED;
}
else
{
// Block all further incoming traffic until we're finished with this command.
// NOTE: This must be turned off when the command is finished or we'll never
// receive another packet.
// NOTE2: This has no effect on a MASTER.
uCommandBlock = 1;
// Copy from rxUserDataArray to rxUserDataCopy in case a new message
// is received while interpretting the last one (only need data portion of buffer).
memcpy(rxUserDataCopy, rxUserDataArray, NUM_USER_BYTES/2*sizeof(u16));
uStatus = SUCCESS; //Good
#if SAVESYMBOLS == TRUE
{
u16 n; // append the freqEq coeficients to the tracebuffer
iCplx *feqPtr = phaseEqArray;
for(n = 0; n < CARRIER_LEN; n++ )
{
SaveTraceData((u16)(feqPtr->re));
SaveTraceData((u16)(feqPtr->im));
feqPtr++;
}
}
#endif
DebugDelay(); // Flush C54x if in debug mode.
DebugDelay(); // Flush C54x if in debug mode.
}
}
else
{
uStatus = ERR_RX_ADDR_MISMATCH;
TurnLEDsOff(LED_RX_PACKET_GOOD); //Turn off green LED4 - packet was not for me.
}
}
}
TurnLEDsOff(LED_RX_FRAME_ALIGN | LED_RX_AGC_HOLD); // Turn off yellow LED5 and yellow LED6
DebugDelay(); // Flush C54x if in debug mode.
return(uStatus);
}
//==========================================================================================
// Function: TestInterruptFlag()
//
// Description: This function reads the interrupt mask flag and posts a trace message
// if it is non-zero (interrupts disabled).
//
// Revision History:
//==========================================================================================
void TestInterruptFlag(u16 uMarker)
{
volatile u16 ST1Shadow;
volatile u16 ST1Shadow2;
#if SAVETRACE == TRUE
u16 uRxDMA;
#endif
NOP(); // Wait for pipeline to clear.
ST1Shadow = ST1; // Read the ST1 reg which contains the interrupt mask
RPTNOP(4); // Wait for pipeline to clear.
ST1Shadow2 = ST1; // Read ST1 again. Was seeing false triggers when they differed.
RPTNOP(4); // Wait for pipeline to clear.
#if SAVETRACE == TRUE
if ( ST1Shadow != ST1Shadow2 ) // Post a trace message if these don't match
{
SaveTraceData(0x1333); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(ST1Shadow); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(ST1Shadow2); //!!!DEBUG Put a marker in the trace buffer
DebugDelay(); // Flush C54x if in debug mode.
DebugDelay(); // Flush C54x if in debug mode.
}
#endif
if ( ((ST1Shadow & 0x0800) != 0) && ((ST1Shadow2 & 0x0800) != 0) )
{
INTR_GLOBAL_ENABLE(); // Re-Enable Global Interrupts
#if SAVETRACE == TRUE
uRxDMA = (u16)ReadRxDMAPointer(); // Read DMA destination pointer in RxBuffer
SaveTraceData(uMarker); //!!!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
DebugDelay(); // Flush C54x if in debug mode.
#endif
DebugDelay(); // Flush C54x if in debug mode.
}
return;
}
//==========================================================================================
// Function: INVALID_ISR()
//
// Description: Handler for Invalid Interrupts.
//
// Revision History:
//==========================================================================================
interrupt void INVALID_ISR(void)
{
volatile u16 hang;
DebugDelay(); // Flush C54x if in debug mode.
// Shut off MCBSP frame sync generation (FS)
MCBSP_SUBREG_BITWRITE(AFE_MCBSP, SPCR2_SUBADDR, FRST, FRST_SZ, 0);
MCBSP_SUBREG_BITWRITE(LED_MCBSP, SPCR2_SUBADDR, FRST, FRST_SZ, 0);
DebugDelay(); // Flush C54x if in debug mode.
#ifdef SHOW_FLOW
printf("Invalid Interrupt: IMR=%X IFR=%X \n", IMR, IFR);
#endif
DebugDelay(); // Flush C54x if in debug mode.
hang = 1; // 0= return immediately, 1= hang until user intervention
while( hang )
{
DebugDelay(); // Flush C54x if in debug mode.
}
}
//==========================================================================================
// Function: TINT0_ISR()
//
// Description: Timer 0 Interrupt Handler
//
// Revision History:
//==========================================================================================
interrupt void TINT0_ISR(void)
{
#define DMSBA_REG (*(volatile unsigned int *) DMSBA_ADDR)
u16 DMAsubAddrShadow; // Backup copy of the DMA base address register
DMAsubAddrShadow = DMSBA_REG; // Make a backup copy of the DMA base address register
// IMPORTANT! This must be done before any other operations that
// might access the DMA registers.
if( agcState != AgcHold )
{
sample_interupt(); // Look at recent received values. Update AGC.
// Set SNRflag when time to look for preamble.
FillIdleBuffer(); // Write new control setting to Tx idle buffer if it has changed
if( SNRflag == 1 )
{
SNRflag = -1; // In Progress
recSignal = lookForPacket(); // Look for preamble pattern in recently received buffer
SNRflag = 0; // Completed
}
}
// Increment one counter to time auto-polling, and two used to keep track of time since
// a PLC packet was sent or received.
ulAutoPollCounter++; // Used for autopoll and finding closest slave
ulUartCounter++;
ulLastRxCounter++;
ulPlcResponseTimeoutCounter++;
ulAutoPollResponseTimeoutCounter++;
ulBerDelayCounter++;
ulFlashWriteCounter++;
uFlashShow++;
// Move any pending characters from the 16C550.
// This is done in the ISR instead of ReceiveUART() so that if we receive more
// characters than fit in the FIFO we won't loose them.
while (UART_LSR_REG & 0x1) // As long as there is data.
{
// Store one character per word.
upUartBufferFifo[uUartBufferPointerIn] = (u16) UART_RBR_REG;
if(++uUartBufferPointerIn >= UART_BUFFER_SIZE)
{
uUartBufferPointerIn = 0;
}
}
// ----- Clean up and restore context ------
DMSBA_REG = DMAsubAddrShadow; // Restore the DMA base address register in case we messed it up
IFR = 1<<TINT0; // Clear the Timer0 Interrupt Flag
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -