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

📄 piolib.c

📁 Vxworks的培训教程,大家分享下啊,
💻 C
字号:
#include "pioLib.h"#include "objLib.h"/* globals */IMPORT DAADIO daadio;PIO pio;/* forward declarations */void pioISR();STATUS pioInit (outputEnableMask, msgQId)	UINT8		outputEnableMask;	/* Mask to set which are output ports */	MSG_Q_ID	msgQId;	{	UINT8 *	pOutputEnablePort;	UINT8 *	pPort;	UINT8	enableMask;	int		port;	int		lockKey;	/* If daadioInit() has not been called, fail */	if (daadio.initialized == FALSE)		{		printf ("daadio not initialized\n");		return (ERROR);		}	/* If mutex semaphore has not been created, do it now */	if (pio.mutexSem == NULL)		{		if ((pio.mutexSem = semMCreate (SEM_Q_PRIORITY|SEM_DELETE_SAFE|									SEM_INVERSION_SAFE)) == NULL)			return (ERROR);		}	/* Initialize <pOutputEnablePort> to point to the output enable register */	pOutputEnablePort = (UINT8 *)daadio.baseAddr + PIO_OUTPUT_ENABLE_OFFSET;	/* Set the output enable register to the mask the user passed us */	*pOutputEnablePort = outputEnableMask;	/* Reset all output channels */	for (port=0, enableMask=outputEnableMask; port<PIO_MAX_PORTS; 		port++, enableMask>>=1)		{		if (enableMask & 1)			{			pPort = (UINT8 *) daadio.baseAddr + PIO_PORT_NUM_TO_OFF (port);			*pPort = (UINT8)0;			}		}	/* If PORT A is an input port and a message queue ID is provided	   then enable PIO interrupts, otherwise insure that they are	   disabled. */	if (((outputEnableMask & 1) == 0) && msgQId)		{		lockKey = intLock();		pio.intMsgQId = msgQId;		*daadio.pIntModSel = daadio.intModSel |= DAADIO_PIO_INT_SEL;		intUnlock (lockKey);		}	else 		{		lockKey = intLock();		pio.intMsgQId = (MSG_Q_ID) 0;		*daadio.pIntModSel = daadio.intModSel &= ~DAADIO_PIO_INT_SEL;		intUnlock (lockKey);		}	pio.initialized = TRUE;	return (OK);	}STATUS pioSet (port, channel, state)	int port, channel;	BOOL state;	{	UINT8 *pPort;	/* pointer to port register */	int channelBit;	/* bit which reflect which channel is being set */	/* Error checking...	 * Ensure pioInit() routine has been called 	 * and the port and channel are within range.	 */		if (pio.initialized == FALSE)		{		printf ("pio not initialized\n");		return (ERROR);		}	if (port < 0 || port >= PIO_MAX_PORTS)		{		printf ("port number out of range\n");		return (ERROR);		}	if (channel < 0 || channel >= PIO_MAX_CHANNELS_PER_PORT)		{		printf ("channel number out of range\n");		return (ERROR);		}	if ((*((UINT8 *)daadio.baseAddr + PIO_OUTPUT_ENABLE_OFFSET) & (1 << port)) 		== 0)		{		printf ("can not set an input port\n");		return (ERROR);		}		/* Initialize <pPort> to point to the appropriate port */	pPort = (UINT8 *) daadio.baseAddr + PIO_PORT_NUM_TO_OFF (port);	/* Set a bit in <channelBit> which reflects which channel is being set, 	   i.e. if channel 0, set bit 0; if channel 1, set bit 1; and so on. */	channelBit = 1 << channel;	/* Update the port register pointed to by <pPort> to be set or unset	   based on the value of <state>. Since this is a read/modify/write	   operation, mutual exclusion needs to be assured. */	if (semTake (pio.mutexSem, WAIT_FOREVER) == ERROR)		return (ERROR);	if (state)		*pPort |=  channelBit;	else		*pPort &= ~channelBit;	semGive (pio.mutexSem);		return (OK);	}int pioGet (port, channel)	int port, channel;	{	UINT8 *pPort;	/* pointer to port register */	int channelBit;	/* bit which reflects which channel is being tested */	BOOL state;		/* whether channel is ON or OFF */	/* Error checking...	 * Ensure that pioInit() routine has been called 	 * and the port and channel are within range.	 */		if (pio.initialized == FALSE)		{		printf ("pio not initialized\n");		return (ERROR);		}	if (port < 0 || port >= PIO_MAX_PORTS)		{		printf ("port number out of range\n");		return (ERROR);		}	if (channel < 0 || channel >= PIO_MAX_CHANNELS_PER_PORT)		{		printf ("channel number out of range\n");		return (ERROR);		}		/* Initialize <pPort> to point to the appropriate port */	pPort = (UINT8 *) daadio.baseAddr + PIO_PORT_NUM_TO_OFF (port);	/* Set a bit in <channelBit> which reflects which channel is being set, 	   i.e. if channel 0, set bit 0; if channel 1, set bit 1; and so on. */	channelBit = 1 << channel;	/* Set <state> to be ON or OFF depending on the state of the channel */	state = (*pPort & channelBit) ? ON : OFF;		return (state);	}void pioPoll (port, msgQId)	int port;	MSG_Q_ID msgQId;	{	PIO_MSG_Q_DATA 	msgQData;	UINT8 			currentState;	UINT8 			lastState = 0;	UINT8 			changedChannels;	UINT8 *			pPort;	UINT8			channelBit;		int 			channel;		IMPORT int		errno;	/* Error checking */	if (pio.initialized == FALSE)		{		printf ("pio not initialized\n");		return;		}	/* Fail if not an input port, i.e. if the corresponding bit in the	   output enable register is on */	if (*((UINT8 *)daadio.baseAddr + PIO_OUTPUT_ENABLE_OFFSET) & (1 << port))		{		printf ("port not an input port\n");		return;		}		/* Initialize <pPort> to point to the appropriate port */	pPort = (UINT8 *) daadio.baseAddr + PIO_PORT_NUM_TO_OFF (port);	FOREVER		{		taskDelay (PIO_POLL_DELAY);		/* Get the current state of all the channels in the port. */		currentState = *pPort;		/* If the state of the channels did not change, loop back. */		if (currentState == lastState)			continue;				/* Identify which channels changed state.  By exclusive or'ing		   the current with the last state, we have, for each channel		   in the port, the corresponding bit set in <changedChannels>. */		changedChannels = currentState ^ lastState;		/* Check each bit in <changedChannels> to see if that channel		   changed state.  <channel> keeps track of which channel		   number we are checking. <channelToCheck> just holds a single		   set bit corresponding with the channel number we are checking		   for. */		for (channel=0; channel<PIO_MAX_CHANNELS_PER_PORT; channel++)			{			/* Set a bit in <channelBit> which reflects the channel			   we are checking. I.e., if channel 0, set bit 0; if 			   channel 1, set bit 1, and so on. */			channelBit = 1 << channel;			/* If the <channelBit> bit is not set in <changedChannels>			   then this <channel> did not change. Loop back and check			   the next channel. */			if (changedChannels & channelBit == 0)				continue;			/* <channel> changed */			/* Initialize the message structure and send it. */			msgQData.port = port;			msgQData.channel = channel;			msgQData.state = (currentState & channelBit) ? ON : OFF;			msgQData.timeStamp = tickGet();				if (pioMsgSend (msgQId, &msgQData) == ERROR)				{				printf ("Msg Queue fatal error: aborting poll task\n");				return;				}			}		/* Update the last state with the current state */		lastState = currentState;		}	}STATUS pioMsgSend (msgQId, pMsgQData)	MSG_Q_ID 			msgQId;	PIO_MSG_Q_DATA *	pMsgQData;	{	IMPORT int		errno;	if (msgQSend (msgQId, (char *) pMsgQData, sizeof (PIO_MSG_Q_DATA),						NO_WAIT, MSG_PRI_NORMAL) == ERROR)		{		/* If failure was because queue is full, print		   warning otherwise return error. */		if (errno == S_objLib_OBJ_UNAVAILABLE)			logMsg ("Msg Queue full, dumping data port %d, channel %d, status is %s at clock tick %d\n", 					pMsgQData->port, pMsgQData->channel, (pMsgQData->state) ? 					"ON" : "OFF", pMsgQData->timeStamp);		else			return (ERROR);		}	return (OK);	}void pioISR (param)	int param;	{	PIO_MSG_Q_DATA	msgQData;	UINT8 *			pPatternReg;	UINT8 *			pPortA;	UINT8 			currentState;	int 			channel;	UINT8			changedChannels;	UINT8 *			pIntModSel;	unsigned		channelBit;	IMPORT int		errno;		/* error checking */	/* If the PIO bit is not set in the interrrupt source module	 * register, then it is not a PIO interrupt. Disable whatever	 * interrupts called us. */	if ((*daadio.pIntSrcMod & DAADIO_PIO_INT_SEL) == 0)		{		logMsg ("pioISR: unknown source module \n");		*daadio.pIntModSel = daadio.intModSel &= ~*daadio.pIntSrcMod;		return;		}	/* If the message queue ID is NULL then PIO interrupts have not 	 * been initialized.  Disable further PIO interrupts.*/	if (pio.intMsgQId == (MSG_Q_ID) 0)		{		logMsg ("pioISR: PIO interrupts not initialized\n");		*daadio.pIntModSel = daadio.intModSel &= ~DAADIO_PIO_INT_SEL;		return;		}	pPatternReg = (UINT8 *)daadio.baseAddr + PIO_PATTERN_REG_OFFSET;	pPortA = (UINT8 *)daadio.baseAddr + PIO_PORT_A_OFFSET;	currentState = *pPortA;	/* Identify which channels changed state.  By exclusive or'ing	   the current state of Port A with the pattern register, we 	   identify the changed channels */	changedChannels = currentState ^ *pPatternReg;	for (channel=0; channel<PIO_MAX_CHANNELS_PER_PORT; channel++)		{		channelBit = 1 << channel;		/* If this channel did not change, don't send message */		if (channelBit & changedChannels == 0)			continue;		msgQData.port = PORT_A;		msgQData.channel = channel;		msgQData.state = (channelBit & currentState) ? ON : OFF;		msgQData.timeStamp = tickGet();			if (pioMsgSend (pio.intMsgQId, &msgQData) == ERROR)			{			logMsg ("Msg Queue fatal error: disabling pio interrupts\n");			*daadio.pIntModSel = daadio.intModSel &= ~DAADIO_PIO_INT_SEL;			}		}	*pPatternReg = currentState;	}

⌨️ 快捷键说明

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