📄 freeportsend.c
字号:
#ifdef VERBOSE
{
mexPrintf("ReverseOrder2 %d:%d >> ", buf[0], buf[1]);
}
#endif /* VERBOSE */
temp = buf[0];
buf[0] = buf[1];
buf[1] = temp;
#ifdef VERBOSE
{
mexPrintf("%d:%d\n", buf[0], buf[1]);
}
#endif /* VERBOSE */
return (void *)buf;
}
// ----------------------------------------------------------------------------------------------------
// mex function
// ----------------------------------------------------------------------------------------------------
/* Function: mexFunction =======================================================
* Abstract:
* Gateway from Matlab.
*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
unsigned int myPort = 1;
unsigned int myBaud = 300;
unsigned int myChannel = 0;
unsigned int myElements = 0;
unsigned char mydType = 0;
unsigned int myRawFlag;
unsigned int buf_size = 0;
unsigned char *buf;
myUsrBuf *admin;
myCOMPort *adminP = NULL;
/* check syntax */
if ((nlhs != 0) || (nrhs != 6)) {
mexErrMsgTxt("Usage: freePortSend(COMx, baudrate, channel, nElememts, dataType, data)\n");
} else {
/* syntax correct -> analyse inputs */
int k = 0;
while(k < 6) {
switch(k) {
case 0:
/* COM port */
if(mxIsNumeric(prhs[k]) && !mxIsComplex(prhs[k])) {
/* get COM port */
myPort = (unsigned int)mxGetScalar(prhs[k]);
if((myPort < 0) || (myPort > 30))
mexErrMsgTxt("Invalid COM port number.\n");
#ifdef VERBOSE
mexPrintf("freePortSend: COMx = %d\n", myPort);
#endif /* VERBOSE */
}
else {
mexErrMsgTxt("Parameter [COMx] needs to be a scalar number.\n");
}
k = k + 1;
break;
case 1:
/* Baudrate */
if(mxIsNumeric(prhs[k]) && !mxIsComplex(prhs[k])) {
int i, m;
/* get Baudrate */
myBaud = (unsigned int)mxGetScalar(prhs[k]);
/* check if this is a valid baudrate */
for(i=0, m=-1; i<numBAUDRATES; i++) {
#ifdef VERBOSE
mexPrintf("freePortSend: Checking baudrate: %d\n", BaudRates[i]);
#endif /* VERBOSE */
if(myBaud == BaudRates[i]) {
#ifdef VERBOSE
mexPrintf("freePortSend: Detected supported baudrate (%d)\n", myBaud);
#endif /* VERBOSE */
m = i;
break;
}
}
if(m == -1) {
mexErrMsgTxt("Unsupported baudrate.\n");
}
}
else {
mexErrMsgTxt("Parameter [baudrate] needs to be a scalar number.\n");
}
k = k + 1;
break;
case 2:
/* channel */
if(mxIsEmpty(prhs[k])) {
/* channel undefined -> raw data transmission */
myRawFlag = 1;
myChannel = 0; /* (ab)using 'channel 0' (admin) */
}
else {
/* channel defined -> formatted transmission */
myRawFlag = 0;
if(mxIsNumeric(prhs[k]) && !mxIsComplex(prhs[k])) {
/* get channel number */
myChannel = (unsigned int)mxGetScalar(prhs[k]);
if((myChannel < 0) || (myChannel > MAX_FREECOM_CHANNELS-1))
mexErrMsgTxt("Invalid channel number.\n");
}
else {
mexErrMsgTxt("Parameter [channel] needs to be a scalar number.\n");
}
}
#ifdef VERBOSE
mexPrintf("freePortSend: Channel = %d\n", myChannel);
mexPrintf("freePortSend: rawdata = %d\n", myRawFlag);
#endif /* VERBOSE */
k = k + 1;
break;
case 3:
/* number of elements */
if(mxIsNumeric(prhs[k]) && !mxIsComplex(prhs[k])) {
/* get number of elements */
myElements = (unsigned int)mxGetScalar(prhs[k]);
if((myElements <= 0) || (myElements > maxNUMELEMENTS))
mexErrMsgTxt("Invalid number of elements.\n");
}
else {
mexErrMsgTxt("Parameter [nElements] needs to be a scalar number.\n");
}
#ifdef VERBOSE
mexPrintf("freePortSend: number of elements = %d\n", myElements);
#endif /* VERBOSE */
k = k + 1;
break;
case 4:
/* data type */
if(mxIsNumeric(prhs[k]) && !mxIsComplex(prhs[k])) {
/* get data type ID */
mydType = (unsigned char)mxGetScalar(prhs[k]);
if((mydType < 0) || (mydType > numDATATYPES-1))
mexErrMsgTxt("Invalid data type ID.\n");
}
else {
mexErrMsgTxt("Parameter [dataType] needs to be a scalar number.\n");
}
/* calculate telegram size */
buf_size = BuiltInDTypeSize[mydType] * myElements;
#ifdef VERBOSE
mexPrintf("freePortSend: data type = %d\n", mydType);
#endif /* VERBOSE */
k = k + 1;
break;
case 5:
/* data */
if(!mxIsEmpty(prhs[k])) {
if(!mxIsNumeric(prhs[k]) || mxIsComplex(prhs[k])) {
mexErrMsgTxt("Parameter [data] needs to be a real-valued vector.\n");
}
else {
/* get data */
if((unsigned int)mxGetNumberOfElements(prhs[k]) != myElements) {
mexErrMsgTxt("Inconsistent number of data elements.\n");
}
/* allocate memory for buffer (buf_size bytes) for channel 'IWork[0]' and its admin structure, returns the access pointer */
if((admin = AllocateUserBuffer(myChannel, buf_size, mydType)) == NULL) {
mexErrMsgTxt("freePortSend: Problem during memory allocation [insufficient memory, admin].\n");
}
/* open port */
/* allocate memory for admin structure of this instance's COM port access */
if((adminP = (myCOMPort *)calloc(1, sizeof(myCOMPort))) == NULL) {
mexErrMsgTxt("freePortSend: Problem during memory allocation [insufficient memory, adminP].\n");
}
/* initialize port access structure */
adminP->access_count = 1;
adminP->hCom = FreePortOpenConnection(myPort, myBaud);
/* get local copy of buffer pointer */
buf = admin->buf;
/* copy data to transmission buffer */
{
unsigned int fi;
unsigned char *pbuf = admin->buf + 4;
double *pData = (double *)mxGetPr(prhs[k]);
for(fi=0; fi<myElements; fi++) {
/* single : ID = 0*/
/* int8 : ID = 1 */
/* uint8 : ID = 2 */
/* int16 : ID = 3 */
/* uint16 : ID = 4 */
/* int32 : ID = 5 */
/* uint32 : ID = 6 */
/* boolean : ID = 7 */
switch(mydType) {
case tSINGLE:
{
float tData = (float)pData[fi];
*((float *)pbuf) = *(float *)(ReverseOrder4((unsigned char *)&tData));
pbuf += BuiltInDTypeSize[mydType];
}
break;
case tINT8:
*((int8_T *)pbuf) = (int8_T)(pData[fi]);
pbuf += BuiltInDTypeSize[mydType];
break;
case tUINT8:
*((uint8_T *)pbuf) = (uint8_T)(pData[fi]);
pbuf += BuiltInDTypeSize[mydType];
break;
case tINT16:
{
int16_T tData = (int16_T)pData[fi];
*((int16_T *)pbuf) = *(int16_T *)(ReverseOrder2((unsigned char *)&tData));
pbuf += BuiltInDTypeSize[mydType];
}
break;
case tUINT16:
{
uint16_T tData = (uint16_T)pData[fi];
*((uint16_T *)pbuf) = *(uint16_T *)(ReverseOrder2((unsigned char *)&tData));
pbuf += BuiltInDTypeSize[mydType];
}
break;
case tINT32:
{
int32_T tData = (int32_T)pData[fi];
*((int32_T *)pbuf) = *(int32_T *)(ReverseOrder4((unsigned char *)&tData));
pbuf += BuiltInDTypeSize[mydType];
}
break;
case tUINT32:
{
uint32_T tData = (uint32_T)pData[fi];
*((uint32_T *)pbuf) = *(uint32_T *)(ReverseOrder4((unsigned char *)&tData));
pbuf += BuiltInDTypeSize[mydType];
}
break;
case tBOOLEAN:
{
boolean_T tData = (boolean_T)pData[fi];
*((boolean_T *)pbuf) = *(boolean_T *)(ReverseOrder2((unsigned char *)&tData));
pbuf += BuiltInDTypeSize[mydType];
}
//*((boolean *)pbuf) = (boolean)(pData[fi]);
//pbuf += BuiltInDTypeSize[mydType];
break;
} /* switch(mydType) */
} /* for */
} /* copy elements to transmission buffer */
} /* numeric and ! complex */
} /* not empty */
else {
mexErrMsgTxt("Empty data vector.\n");
}
#ifdef VERBOSE
mexPrintf("freePortSend: buffer size = %d\n", buf_size);
#endif /* VERBOSE */
k = k + 1;
break;
} /* switch */
} /* while [paramters] */
} /* else: syntax correct */
/* -------------------------------------------------------------------------------------------- */
/* at this stage, the transmission data structure has been populated and is ready to be sent... */
/* -------------------------------------------------------------------------------------------- */
/* download data to the target */
if(myRawFlag == 0) {
/* formatted telegram */
Send(adminP->hCom, buf, (DWORD)buf[0], no_echo, &SendTimeoutFlag, with_to_messages);
#ifdef VERBOSE
{
unsigned int i;
mexPrintf("TX on channel %d >> ", myChannel);
/* new buffer... */
for(i=0; i<buf_size+4; i++)
mexPrintf(":%d", (unsigned int)buf[i]);
mexPrintf(": <<\n");
}
#endif /* VERBOSE */
} else {
/* raw data */
Send(adminP->hCom, (uint8_T *)&buf[4], (DWORD)buf_size, no_echo, &SendTimeoutFlag, with_to_messages);
#ifdef VERBOSE
{
unsigned int i;
mexPrintf("TX on channel %d >> ", myChannel);
/* new buffer... */
for(i=4; i<buf_size+4; i++)
mexPrintf(":%d", (unsigned int)buf[i]);
mexPrintf(": <<\n");
}
#endif /* VERBOSE */
}
// TERMINATE, delete data buffers
free(admin->buf);
free(admin);
/* decrement port access pointer */
adminP->access_count -= 1;
/* check access counter */
if(adminP->access_count == 0) {
/* close port */
FreePortCloseConnection(adminP->hCom);
/* delete port access structure */
free(adminP);
}
} /* end mexFunction */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -