📄 mex_modem.c
字号:
/*=================================================================================
Filename: mex_modem.c
Description: Mex function call for OFDM powerline modem
Copyright (C) 2000 - 2003 Texas Instruments Incorporated
Texas Instruments Proprietary Information
Use subject to terms and conditions of TI Software License Agreement
Revision History:
========================================================================*/
#include "ofdm_modem.h"
//---- Input Arguments ---------
#define CMD_STR prhs[0]
#define PARM1 prhs[1]
#define PARM2 prhs[2]
//---- Output Arguments --------
#define OUT1 plhs[0]
#define OUT2 plhs[1]
#define OUT3 plhs[2]
#define MAKE_FIELD(a) #a, a
#define MAKE_FUNC_PTR(a) #a, ((void *)a)
/*===============================================================
local function prototypes
===============================================================*/
void getUserDataFromMatlab(u16 *userData, const mxArray *matInArray);
void copyWaveform2Matlab( const mxArray **matOutArray, i16 *pTxSignal);
i16 *getSignalFromMatlab(dCplxPtr dRecSignal, int startingSample);
double copyReadData2Matlab(dCplxPtr dDataBuffer, u16 *userData, i16 parityGood );
//void parms2Matlab( const mxArray **matOutArray );
void parms2Matlab( mxArray **matOutArray );
u16 readDataFramesFromMatlab( u16 *pUserData, dCplxPtr drec );
static void cleanup(void);
/*==============================================================
I/O function
calling syntax:
[errorCount, userData] = ofdm_dataDet(recSignal, dataStart)
===============================================================*/
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
char *CmdStr;
char prtStr[80];
int n;
//---- transmit vars -----------------------
i16 *pTxSignal;
i16 winSignal[WINDOW_LEN];
//---- agc vars -----------------------
dCplxPtr drec;
dCplxPtr drecAgc;
double *dBufferPos;
i16 *recPtr;
//---- receive vars -----------------------
i16 errCount = 0;
double *errorCountPtr = NULL;
dCplxPtr dDataBuffer;
//i16 *recSignal; // use global version instead
#if DEBUGIT > DEBUG_NONE
diag.r = NULL;
diag.i = NULL;
#endif
//---- get command string ----------------------------
if( mxIsChar(CMD_STR) != 1 )
mexErrMsgTxt("First argument must be a command string");
n = 1 + ( mxGetM(CMD_STR)*mxGetN(CMD_STR) ); // Get input command string
CmdStr = mxCalloc(n, sizeof(char));
n = mxGetString(CMD_STR, CmdStr, n);
if( n != 0 )
mexErrMsgTxt("Error allocating command string.");
/*====================================================================
Decode command and call associated functions
Decode "XMIT"
=====================================================================*/
if( strcmp(CmdStr, "xmit")==0 )
{
//---- Check for proper number of arguments ---------------
if( nlhs != 1 )
mexErrMsgTxt("Unexpected number of output arguments.");
if( nrhs != 2 )
mexErrMsgTxt("Syntax: [pTxSignal] = mex_modem('xmit', userData)");
getUserDataFromMatlab(txUserDataArray, PARM1);
/*======================================================================
generate transmit signal
======================================================================*/
pTxSignal = makePreamble(txSignalArray, winSignal); // start at current ptr and build preamble
pTxSignal = makeDataFrames( pTxSignal, winSignal, txUserDataArray); // start a current ptr and build data frames
/*======================================================================
copy the waveform back to Matlab
======================================================================*/
copyWaveform2Matlab(&OUT1, txSignalArray);
}
/*====================================================================
Decode "REC"
=====================================================================*/
else if( strcmp(CmdStr, "rec")==0 )
{
//---- Check for proper number of arguments ---------------
if( nrhs != 2 )
mexErrMsgTxt("Wrong number of input arguments.\nSyntax: [errorCount, userData, rxAgc] = mex_modem('rec', recSignal)");
//---- input vars ---------------------------
drec.i = NULL;
drec.r = mxGetPr(PARM1);
drec.len = mxGetM(PARM1)*mxGetN(PARM1);
//---- Allocate output vars ---------------------------
dDataBuffer.len = DATA_BUFFER_LEN*2;
dDataBuffer.r = NULL;
dDataBuffer.i = NULL;
drecAgc.r = NULL;
switch( nlhs )
{
case 3:
OUT3 = mxCreateDoubleMatrix(mxGetM(PARM1), mxGetN(PARM1), mxREAL);
drecAgc.r = mxGetPr(OUT3);
drecAgc.i = NULL;
drecAgc.len = drec.len;
case 2:
OUT2 = mxCreateDoubleMatrix(dDataBuffer.len, 1, mxREAL);
dDataBuffer.r = mxGetPr(OUT2);
case 1:
OUT1 = mxCreateDoubleMatrix(1, 1, mxREAL);
errorCountPtr = mxGetPr(OUT1);
break;
default:
mexErrMsgTxt("Unexpected number of output arguments.");
}
/*====================================================================
do agc : get signal from Matlab, AGC, return AGC-ed signal if requested
detect packet and return pointer to signal
=====================================================================*/
recSignal = lookForPacket( drecAgc, drec );
/*====================================================================
do frame align & equalization
=====================================================================*/
recSignal = frameAlign(phaseEqArray, recSignal );
if (frameAligned == 0 )
postError("stopped");
/*====================================================================
read data and do detection
=====================================================================*/
errCount = readDataFrames(rxUserDataArray, recSignal, phaseEqArray );
//---- return the results to Matlab---------------------------------
*errorCountPtr = copyReadData2Matlab(dDataBuffer, rxUserDataArray, errCount );
}
/*====================================================================
Report modem parameters back to Matlab
=====================================================================*/
else if( strcmp(CmdStr, "parm")==0 )
{
//---- Check for proper number of arguments ---------------
if( nlhs != 1 )
mexErrMsgTxt("Need variable assignment to accept structure of parameters.\nSyntax: parmStruct = mex_modem('parm')");
parms2Matlab(&OUT1);
}
/*====================================================================
Decode "Align"
=====================================================================*/
else if( strcmp(CmdStr, "align")==0 )
{
int n;
iCplx *feqPtr;
//---- Check for proper number of arguments ---------------
if( nrhs != 3 )
mexErrMsgTxt("Wrong number of input arguments.\nSyntax: [freqEq] = mex_modem('align', recSignal, packetStart)");
//---- input vars ---------------------------
drec.i = NULL;
drec.r = mxGetPr(PARM1);
drec.len = mxGetM(PARM1)*mxGetN(PARM1);
if( drec.len > RX_CIRC_BUFFER_LEN )
mexErrMsgTxt("recSignal data passed is too big.");
n = (int)(*mxGetPr(PARM2)); // recSignal starts at this offset
recSignal = recSignalArray + n;
//---- Allocate output vars ---------------------------
if( nlhs != 1)
mexErrMsgTxt("Wrong number of output arguments");
OUT1 = mxCreateDoubleMatrix(CARRIER_LEN, 1, mxCOMPLEX);
drecAgc.r = mxGetPr(OUT1);
drecAgc.i = mxGetPi(OUT1);
drecAgc.len = CARRIER_LEN;
//---- get receive data -------------------------
recPtr = recSignalArray;
for( n = 0; n < drec.len; n++ )
{
*recPtr = (i16)(*drec.r++);
recPtr++;
}
// ---- do frame align & equalization ----------------------
recSignal = frameAlign(phaseEqArray, recSignal );
feqPtr = phaseEqArray;
for( n = 0; n < CARRIER_LEN; n++ )
{
*drecAgc.r++ = feqPtr->re;
*drecAgc.i++ = feqPtr->im;
feqPtr++;
}
}
/*====================================================================
Decode "SYMB"
=====================================================================*/
else if( strcmp(CmdStr, "symb")==0 )
{
u16 n;
//---- Check for proper number of arguments ---------------
if( nrhs != 2 )
mexErrMsgTxt("Wrong number of input arguments.\nSyntax: [errorCount, <userData>, <freqEq>] = mex_modem('symb', symbolArray)");
//---- Allocate output vars ---------------------------
dDataBuffer.len = DATA_BUFFER_LEN*2;
dDataBuffer.r = NULL;
dDataBuffer.i = NULL;
drecAgc.r = NULL;
drecAgc.i = NULL;
switch( nlhs )
{
case 3:
OUT3 = mxCreateDoubleMatrix(CARRIER_LEN, 1, mxCOMPLEX);
drecAgc.r = mxGetPr(OUT3);
drecAgc.i = mxGetPi(OUT3);
drecAgc.len = CARRIER_LEN;
case 2:
OUT2 = mxCreateDoubleMatrix(dDataBuffer.len, 1, mxREAL);
dDataBuffer.r = mxGetPr(OUT2);
case 1:
OUT1 = mxCreateDoubleMatrix(1, 1, mxREAL);
errorCountPtr = mxGetPr(OUT1);
break;
default:
mexErrMsgTxt("Unexpected number of output arguments.");
}
/*====================================================================
get equalization data
=====================================================================*/
drec.len = mxGetM(PARM1)*mxGetN(PARM1);
drec.r = mxGetPr(PARM1);
drec.i = NULL;
if( drecAgc.r != NULL )
{
if( drec.len < (CARRIER_LEN*2*(DATA_FRAMES_PER_BLOCK*NUM_DATA_BLOCKS+1)) )
mexErrMsgTxt("Trace buffer is to short to get freq Eq data!");
drec.r += CARRIER_LEN*2*DATA_FRAMES_PER_BLOCK*NUM_DATA_BLOCKS;
for( n = 0; n < CARRIER_LEN; n++ )
{
*drecAgc.r++ = *drec.r++;
*drecAgc.i++ = *drec.r++;
}
drec.r = mxGetPr(PARM1);
}
if( drec.len < (CARRIER_LEN*2*DATA_FRAMES_PER_BLOCK*NUM_DATA_BLOCKS) )
mexErrMsgTxt("Trace buffer is to short get all symbols!");
/*====================================================================
read data and do detection
=====================================================================*/
errCount = readDataFramesFromMatlab(rxUserDataArray, drec );
//---- return the results to Matlab---------------------------------
*errorCountPtr = copyReadData2Matlab(dDataBuffer, rxUserDataArray, errCount );
}
/*====================================================================
Decode "SYMB"
=====================================================================*/
else if( strcmp(CmdStr, "symOld")==0 )
{
u16 n;
//---- Check for proper number of arguments ---------------
if( nrhs != 2 )
mexErrMsgTxt("Wrong number of input arguments.\nSyntax: [errorCount, <userData>, <freqEq>] = mex_modem('symb', symbolArray)");
//---- input vars ---------------------------
drec.i = NULL;
drec.r = mxGetPr(PARM1);
drec.len = mxGetM(PARM1)*mxGetN(PARM1);
//---- Allocate output vars ---------------------------
dDataBuffer.len = DATA_BUFFER_LEN*2;
dDataBuffer.r = NULL;
dDataBuffer.i = NULL;
drecAgc.r = NULL;
drecAgc.i = NULL;
switch( nlhs )
{
case 3:
OUT3 = mxCreateDoubleMatrix(CARRIER_LEN, 1, mxCOMPLEX);
drecAgc.r = mxGetPr(OUT3);
drecAgc.i = mxGetPi(OUT3);
drecAgc.len = CARRIER_LEN;
case 2:
OUT2 = mxCreateDoubleMatrix(dDataBuffer.len, 1, mxREAL);
dDataBuffer.r = mxGetPr(OUT2);
case 1:
OUT1 = mxCreateDoubleMatrix(1, 1, mxREAL);
errorCountPtr = mxGetPr(OUT1);
break;
default:
mexErrMsgTxt("Unexpected number of output arguments.");
}
/*====================================================================
get equalization data
=====================================================================*/
if( drecAgc.r != NULL )
{
for( n = 0; n < CARRIER_LEN; n++ )
{
*drecAgc.r++ = *drec.r++;
*drecAgc.i++ = *drec.r++;
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -