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

📄 freeportreceive.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 2 页
字号:
						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("freePortReceive: Channel = %d\n", myChannel);
					mexPrintf("freePortReceive: 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");

						/* set dimensions of the output array (n x 1) */
						dims[0] = myElements;
						dims[1] = 1;
						
					}
					else {
						
						mexErrMsgTxt("Parameter [nElements] needs to be a scalar number.\n");
						
					}	
					
					#ifdef VERBOSE
					mexPrintf("freePortReceive: 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("freePortReceive: data type = %d\n", mydType);
					#endif /* VERBOSE */
					
					k = k + 1;
					break;
					
				case 5:
					
					/* blockingFlag */
					if(mxIsNumeric(prhs[k]) && !mxIsComplex(prhs[k])) {
						
						/* get data type ID */
						myBlockingFlag = (unsigned int)mxGetScalar(prhs[k]);
						
						if((myBlockingFlag != 0) && (myBlockingFlag != 1))
							mexErrMsgTxt("Invalid value of 'blockingFlag'.\n");
					}
					else {
						
						mexErrMsgTxt("Parameter [blockingFlag] needs to be a scalar number.\n");
						
					}
					
					#ifdef VERBOSE
					mexPrintf("freePortReceive: blockingFlag = %d\n", myBlockingFlag);
					#endif /* VERBOSE */
					
					k = k + 1;
					break;
					
			} /* switch */
			
		} /* while [input paramters] */

		
		#ifdef VERBOSE
		mexPrintf("freePortReceive: Checked all inputs\n");
		#endif /* VERBOSE */

		/* prepare output array (1 column, 'nElements' rows) */
		switch(mydType) {
				
			case tSINGLE:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxSINGLE_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
			case tINT8:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxINT8_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
			case tUINT8:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxUINT8_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
			case tINT16:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxINT16_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
			case tUINT16:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxUINT16_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
			case tINT32:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxINT32_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
			case tUINT32:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxUINT32_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
			case tBOOLEAN:
				pArray = mxCreateNumericArray(2, (int const *)&dims[0], mxUINT32_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
				break;
				
		} /* switch(mydType) */
	
        /* get pointer to output buffer */
        outBuf = (unsigned char *)mxGetPr(pArray);
            
		/* create output 'nElementsReceived' */
		pArray2 = mxCreateDoubleMatrix(1, 1, mxREAL);

        /* get pointer to output buffer */
        outnEls = (double *)mxGetPr(pArray2);

		/* initialize number of elements received */
		*outnEls = 0.0;

		#ifdef VERBOSE
		mexPrintf("freePortReceive: Created output variables.\n");
		#endif /* VERBOSE */

	} /* else: syntax correct */


	/* manage channels (workspace variable 'FreePortAdminVar') */
	
	/* create 'FreePortAdminVar' in the base workspace -- if required (first use) */
	if((FreePortAdminVar = mexGetVariable("base", "FreePortAdminVar")) == NULL) {

		int  i;

		/* FreePortAdminVar doesn't exist -> create & initialise it */
		FreePortAdminVar = mxCreateNumericMatrix(MAX_NUM_COM_PORTS, 1, mxUINT32_CLASS, mxREAL);

		/* initialise the array to be stored in variable FreePortAdminVar */
		myPtr = (myCOMPort **)mxGetPr(FreePortAdminVar);

		/* initialise all COM port access pointers with NULL */
		for(i=0; i<MAX_NUM_COM_PORTS; i++) myPtr[i] = NULL;

		#ifdef VERBOSE
		mexPrintf("FreePortAdminVar created\n");
		#endif /* VERBOSE */

	}
	else {

		/* 'FreePortAdminVar' already exists -> get pointer to data in FreePortAdminVar */
		myPtr = (myCOMPort **)mxGetPr(FreePortAdminVar);

		#ifdef VERBOSE
		mexPrintf("FreePortAdminVar found in workspace.\n");
		#endif /* VERBOSE */
	}

	/* open port */
	/* only open port if it's not already open */
	if(myPtr[myPort] == NULL) {

		/* allocate memory for admin structure of this instance's COM port access */
		if((adminP = (myCOMPort *)calloc(1, sizeof(myCOMPort))) == NULL) {
			mexErrMsgTxt("freePortReceive: Problem during memory allocation [insufficient memory, adminP].\n");
		}
				
		/* initialize port access structure */
		adminP->access_count = 1;
		adminP->hCom = FreePortOpenConnection(myPort, myBaud);
							
		/* store port access pointer in workspace variable */
		myPtr[myPort] = adminP;

		#ifdef VERBOSE
		mexPrintf("freePortReceive: buffer size = %d\n", buf_size);
		#endif /* VERBOSE */

	}

	/* export variable FreePortAdminVar to the base workspace */
	mexPutVariable("base", "FreePortAdminVar", FreePortAdminVar);

				
	#ifdef VERBOSE
	mexPrintf("freePortReceive: All initialized -> checking COM buffer for data.\n");
	#endif /* VERBOSE */

	/* -------------------------------------------------------------------------------------------------- */
	/* at this stage, the parameters have been checked and memory has been allocated -> wait for data ... */
    /* -------------------------------------------------------------------------------------------------- */

	/* myBlockingFlag */
	do {
	
		/* check COM port for newly arrived data */
		if(checkCOMforData(adminP->hCom) > 0) {


			#ifdef VERBOSE
			mexPrintf("freePortReceive: Found data in COM buffer.\n");
			#endif /* VERBOSE */

			/* receive data...  */
			if(myRawFlag == 0) {
			
				/* formatted telegrams -> receive header */
				uint8_T   myBuf[4];
			
				#ifdef VERBOSE
				mexPrintf("%d bytes in buffer\n", checkCOMforData(adminP->hCom));
				#endif

				/* receive first 4 data bytes from serial port buffer */
				if (!Receive (adminP->hCom, myBuf, 4, &ReceiveTimeoutFlag, with_to_messages)) {
					mexErrMsgTxt("freePortReceive: Error during reception of first 4 bytes.\n");
				}

				#ifdef VERBOSE
				mexPrintf("Header: %d:%d:%d:%d\n", (uint16_T)myBuf[0], (uint16_T)myBuf[1], (uint16_T)myBuf[2], (uint16_T)myBuf[3]);
				#endif /* VERBOSE */

				/* determine telegram size, etc. */
				channel = myBuf[1];
				
			} else {

				/* unformatted data -> channel number '0' (set above) */
				channel = myChannel;

			}
				
			
			/* all remaining parameters are independent of the telegram format */

			
			/* allocate memory for buffer (buf_size bytes) for the received channel and its admin structure, returns the access pointer */
			if((admin = AllocateUserBuffer(channel, buf_size, mydType)) == NULL) {
				mexErrMsgTxt("freePortReceive: Problem during memory allocation [insufficient memory, admin].\n");
			}
									
			/* store the access pointer in the global buffer contents variable */
			freecomTelBuf[channel] = admin;

			size    = admin->buf_size;
			buf     = admin->buf;

			/* receive remaining 'size' data bytes from serial port buffer */
			if (!Receive (adminP->hCom, buf, size, &ReceiveTimeoutFlag, with_to_messages)) {
				mexErrMsgTxt("freePortReceive: Error during reception of remaining bytes.\n");
			}

			#ifdef VERBOSE
			/* host DLL -> echo... */
			{

				uint_T	i;

				mexPrintf("RxD < Channel[%d] ", channel);
			
				/* new buffer... */
				for(i=0; i<size; i++)
					mexPrintf(":%d", (uint_T)buf[i]);

				mexPrintf(":\n");

			}
			#endif /* VERBOSE */

			/* indicate receipt of a telegram */
			admin->buffer_full = 1;

			/* break 'while' loop */
			myBlockingFlag = 0;

		} /* checkCOMforData() */

	} while(myBlockingFlag == 1);

	
	/* check if output of this instance needs updated... */
	admin = freecomTelBuf[myChannel];

	if(admin != NULL) {

		if(admin->buffer_full) {

			/* new data available -> descramble */
			{
				
				unsigned int	fi;
				unsigned char	*pbuf = receivebuf;

				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	*pData = (float *)buf;
							float	tData = (float)pData[fi];
							
							*((float *)pbuf) = *(float *)(ReverseOrder4((unsigned char *)&tData));
							pbuf += BuiltInDTypeSize[mydType];
						}
						break;
						
					case tINT8:
						
						*((int8_T *)pbuf) = (int8_T)(buf[fi]);
						pbuf += BuiltInDTypeSize[mydType];
						break;
						
					case tUINT8:
						
						*((uint8_T *)pbuf) = (uint8_T)(buf[fi]);
						pbuf += BuiltInDTypeSize[mydType];
						break;
						
					case tINT16:
						{
							int16_T	*pData = (int16_T *)buf;
							int16_T	tData = (int16_T)pData[fi];
							
							*((int16_T *)pbuf) = *(int16_T *)(ReverseOrder2((unsigned char *)&tData));
							pbuf += BuiltInDTypeSize[mydType];
						}
						break;
						
					case tUINT16:
						{
							uint16_T	*pData = (uint16_T *)buf;
							uint16_T	tData = (uint16_T)pData[fi];
							
							*((uint16_T *)pbuf) = *(uint16_T *)(ReverseOrder2((unsigned char *)&tData));
							pbuf += BuiltInDTypeSize[mydType];
						}
						break;
						
					case tINT32:
						{
							int32_T	*pData = (int32_T *)buf;
							int32_T	tData = (int32_T)pData[fi];
							
							*((int32_T *)pbuf) = *(int32_T *)(ReverseOrder4((unsigned char *)&tData));
							pbuf += BuiltInDTypeSize[mydType];
						}
						break;
						
					case tUINT32:
						{
							uint32_T	*pData = (uint32_T *)buf;
							uint32_T	tData = (uint32_T)pData[fi];
							
							*((uint32_T *)pbuf) = *(uint32_T *)(ReverseOrder4((unsigned char *)&tData));
							pbuf += BuiltInDTypeSize[mydType];
						}
						break;
						
					case tBOOLEAN:
						{
							boolean_T	*pData = (boolean_T *)buf;
							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 */
				
			} /* descramble */

			
			/* new data might be for this instance -> copy appropriate data to the output array */
			#ifdef VERBOSE
			mexPrintf("freePortReceive: Copying %d bytes to output of channel %d\n", admin->buf_size, myChannel);
			#endif

			/* new data available for this instance -> update output */
			memcpy(outBuf, receivebuf, admin->buf_size);

			/* adjust number of elements received */
			*outnEls = (double)myElements;

			/* clear buffer full flag */
			admin->buffer_full = 0;

		} /* new data available for this instance */

	} /* admin != NULL */

	
	// TERMINATE, delete data buffers
	#ifdef VERBOSE
	mexPrintf("freePortReceive: Terminating - freeing buffers\n");
	#endif

	/* update workspace variable 'FreePortAdminVar' */
	if((FreePortAdminVar = mexGetVariable("base", "FreePortAdminVar")) == NULL) {

		// do nothing, just exit
		mexErrMsgTxt("freePortReceive: Error accessing workspace variable FreePortAdminVar (terminating).\n");
	
	}
	else {

		myUsrBuf  *admin = freecomTelBuf[myChannel];
	
		if(admin != NULL) {
			
			/* yep -> close channel and free memory */
			free(admin->buf);
			free(admin);

			/* reset the channel specific access pointer */
			freecomTelBuf[myChannel] = NULL;

		}
	
		/* get FreePortAdminVar */
		myPtr = (myCOMPort **)mxGetPr(FreePortAdminVar);

		/* decrement port access pointer */
		myPtr[myPort]->access_count -= 1;
	
		/* check access counter */
		if(myPtr[myPort]->access_count == 0) {

			/* close port */
			FreePortCloseConnection(myPtr[myPort]->hCom);

			/* delete port access structure */
			free(myPtr[myPort]);
			myPtr[myPort] = NULL;

		}

		/* export variable FreePortAdminVar to the base workspace */
		mexPutVariable("base", "FreePortAdminVar", FreePortAdminVar);

	} /* FreeBufferAdminVar exists */


	// return output array pointer (always)
	#ifdef VERBOSE
	mexPrintf("freePortReceive: Returning output array.\n");
	#endif
	plhs[0] = pArray;
	plhs[1] = pArray2;

} /* end mexFunction */

⌨️ 快捷键说明

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