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

📄 s3c2410xsio.c.bak

📁 s3c2410的vxworksBSP
💻 BAK
📖 第 1 页 / 共 2 页
字号:
	int lvl;
    
	switch (request)
	{
	case SIO_BAUD_SET:
		if(arg < s3c2410x_BAUD_MIN || arg > s3c2410x_BAUD_MAX) return(EIO);
		
		/* disable interrupts during chip access */
		oldlevel = intLock ();
		s3c2410x_UART_REG_WRITE(pChan,OFFSET_UDIV,(((s3c2410x_PCLK/16)/arg)-1));
		intUnlock (oldlevel);
		s3c2410x_UART_REG_READ(pChan,OFFSET_UDIV,tempUINT32);
		pChan->baudRate=((s3c2410x_PCLK/16)/(tempUINT32+1));
		break;
	case SIO_BAUD_GET:
		*(int *)arg = pChan->baudRate;
		break;
	case SIO_MODE_SET:
		switch(arg)
		{
		case SIO_MODE_INT:
			/* clear subpend-flag of RX_TX */
			switch((int)(pChan->regs))
			{
			case UART_1_BASE_ADR:
				s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,((1<<SUBINT_LVL_TXD1)|(1<<SUBINT_LVL_RXD1)));
				break;
			case UART_0_BASE_ADR:
			default:
				s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,((1<<SUBINT_LVL_TXD0)|(1<<SUBINT_LVL_RXD0)));
			}
				
			/* enable uart_int */
			intEnable(pChan->intLevelRx);

			/* enable subInterrupt for UART0. */
			s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
			switch((int)(pChan->regs))
			{
			case UART_1_BASE_ADR:
				tempUINT32 &= ~((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
				break;
			case UART_0_BASE_ADR:
			default:
				tempUINT32 &= ~((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
			}
			s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
			break;

		case SIO_MODE_POLL:
			/* disable uart_int */
			intDisable(pChan->intLevelRx);

			/* disable subInterrupt for UART0. */
			s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
			switch((int)(pChan->regs))
			{
			case UART_1_BASE_ADR:
				tempUINT32 |= ((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
				break;
			case UART_0_BASE_ADR:
			default:
				tempUINT32 |= ((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
			}
			s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
			break;

		default: return(EIO);
		}
		pChan->channelMode = arg;
		break;
	case SIO_MODE_GET:
		*(int *)arg = pChan->channelMode;
		break;
	case SIO_AVAIL_MODES_GET:
		/* Get the available modes and return OK.  */
		*(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; 
		break;
	case SIO_HW_OPTS_SET:

		if(arg & 0xffffff00) return EIO;
		
		/* do nothing if options already set */
		if(pChan->options == arg) break;

		switch (arg & CSIZE)
		{
		case CS5:
			tempUINT32 = DATABIT_5; break;
		case CS6:
			tempUINT32 = DATABIT_6; break;
		case CS7:
			tempUINT32 = DATABIT_7; break;
		default:
		case CS8:
			tempUINT32 = DATABIT_8; break;
		}

		if (arg & STOPB)
		{
			tempUINT32 |= TWO_STOPBIT;
		}
		else
		{
			/* tempUINT32 &= ~TWO_STOPBIT */;
		}
		
		
		switch (arg & (PARENB|PARODD))
		{
		case PARENB|PARODD:
			tempUINT32 += ODD_PARITY;
			break;
		case PARENB:
			tempUINT32 += EVEN_PARITY;
			break;
		case 0:
		default:
			;/* no parity */
		}

		lvl = intLock();
    		s3c2410x_UART_REG_WRITE(pChan,OFFSET_ULCON,tempUINT32);
		intUnlock(lvl);

		if (arg & CLOCAL)
		{
        		/* clocal disables hardware flow control */
			lvl = intLock();
			s3c2410x_UART_REG_WRITE(pChan,OFFSET_UMCON,AFC_OFF);
			intUnlock(lvl);
		}
		else
		{
			lvl = intLock();
			s3c2410x_UART_REG_WRITE(pChan,OFFSET_UMCON,AFC_ON);
			intUnlock(lvl);
		}

		pChan->options = arg;
		break;
	case SIO_HW_OPTS_GET:
		*(int*)arg = pChan->options;
		return (OK);
	case SIO_HUP:
		/* check if hupcl option is enabled */
		break;
	case SIO_OPEN:
		break; /* always open */
	default:
		return (ENOSYS);
	}
	return (OK);
}

/*
 * s3c2410xSioIntTx - handle a transmitter interrupt 
 *
 * This routine handles write interrupts from the UART.
 *
 * RETURNS: N/A
 */

void s3c2410xSioIntTx 
	(
		s3c2410x_CHAN *	pChan	/* ptr to s3c2410x_CHAN describing this channel */
	)
{
	char outChar;

	/* clear subpending of the TXn */
	switch((int)(pChan->regs))
	{
	case UART_1_BASE_ADR:
		s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_TXD1));
		break;
	case UART_0_BASE_ADR:
	default:
		s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_TXD0));
	}
	
	if((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
	{
		/* write char. to Transmit Holding Reg. */
		s3c2410x_UART_REG_WRITE(pChan, OFFSET_UTXH, (((UINT32)outChar)&0x000000ff));
	}
}
/*
 * s3c2410xSioIntRx - handle a receiver interrupt 
 *
 * This routine handles read interrupts from the UART.
 *
 * RETURNS: N/A
 */

void s3c2410xSioIntRx
	(
		s3c2410x_CHAN *	pChan	/* ptr to s3c2410x_CHAN describing this channel */
	)
{
	char inchar;

	/* clear subpending of the RXn */
	switch((int)(pChan->regs))
	{
	case UART_1_BASE_ADR:
		s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_RXD1));
		break;
	case UART_0_BASE_ADR:
	default:
		s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_RXD0));
	}
	
	/* read character from Receive Holding Reg. */
	s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, inchar);

	(*pChan->putRcvChar) (pChan->putRcvArg, inchar);
}
/*
 * s3c2410xSioInt - handle any UART interrupt
 *
 * This routine handles interrupts from the UART and determines whether
 * the source is a transmit interrupt or receive/receive-timeout interrupt.
 *
 * The Prime Cell UART generates a receive interrupt when the RX FIFO is
 * half-full, and a receive-timeout interrupt after 32 bit-clocks have
 * elapsed with no incoming data.
 *
 * RETURNS: N/A
 */

void s3c2410xSioInt
	(
		s3c2410x_CHAN * pChan   /* ptr to s3c2410x_CHAN describing this channel */
	)
{
	UINT32 intId;

	s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SUBSRCPND, intId);

	if(intId & ((1<<SUBINT_LVL_TXD0)|(1<<SUBINT_LVL_TXD1)))
	{
		s3c2410xSioIntTx(pChan);
		
	}

	if(intId & ((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_RXD1)))
	{
		s3c2410xSioIntRx (pChan);
	}

	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK, 0);
	/* clear pend and enable this level */
	/*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, (1<<(pChan->intLevelRx)));
	s3c2410xIntLvlEnable(pChan->intLevelRx);
	*/
}


/*
 * s3c2410xTxStartup - transmitter startup routine
 *
 * Enable interrupt so that interrupt-level char output routine will be called.
 *
 * RETURNS: OK on success, ENOSYS if the device is polled-only, or
 * EIO on hardware error.
 */

LOCAL int s3c2410xTxStartup
	(
		SIO_CHAN *	pSioChan	/* ptr to SIO_CHAN describing this channel */
	)
{

	s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;

	if(pChan->channelMode == SIO_MODE_INT)
	{
		intEnable(pChan->intLevelTx);

		s3c2410xSioIntTx(pChan);

		return OK;
	}
	else
	{
		return ENOSYS;
	}
}

/*
 * s3c2410xPollOutput - output a character in polled mode.
 *
 * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
 * if the output buffer is full, ENOSYS if the device is interrupt-only.
 */
LOCAL int s3c2410xPollOutput
	(
		SIO_CHAN* pSioChan,	/* ptr to SIO_CHAN describing this channel */
		char      outChar 	/*  to output */
	)
{
	s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
	FAST UINT32 pollStatus;

	s3c2410x_UART_REG_READ(pChan, OFFSET_UTRSTAT, pollStatus);

	/* is the transmitter ready to accept a character? */
	if(!(pollStatus & UTRSTAT_TRNSR_EM))
	{
		return EAGAIN;
	}

	/* write out the character */
	s3c2410x_UART_REG_WRITE(pChan, OFFSET_UTXH, outChar);	/* transmit character */

	return OK;
}
/*
 * s3c2410xPollInput - poll the device for input.
 *
 * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
 * if the input buffer is empty, ENOSYS if the device is interrupt-only.
 */
LOCAL int s3c2410xPollInput
	(
		SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */
		char*	 thisChar	/* pointer to where to return character */
	)
{
	s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
	FAST UINT32 pollStatus;

	s3c2410x_UART_REG_READ(pChan, OFFSET_UTRSTAT, pollStatus);

	if(!(pollStatus & UTRSTAT_RB_RDY))
	{
		return EAGAIN;
	}

	/* got a character */
	s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, *thisChar);

	return OK;
}

/*
 * s3c2410xCallbackInstall - install ISR callbacks to get/put chars.
 *
 * This routine installs interrupt callbacks for transmitting characters
 * and receiving characters.
 *
 * RETURNS: OK on success, or ENOSYS for an unsupported callback type.
 *
 */
LOCAL int s3c2410xCallbackInstall
	(
		SIO_CHAN*	pSioChan,	/* ptr to SIO_CHAN describing this channel */
		int		callbackType,	/* type of callback */
		STATUS	(*callback)(),	/* callback */
		void*	callbackArg	/* parameter to callback */
	)
{
	s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;

	switch(callbackType)
	{
	case SIO_CALLBACK_GET_TX_CHAR:
		pChan->getTxChar	= callback;
		pChan->getTxArg		= callbackArg;
		return OK;

	case SIO_CALLBACK_PUT_RCV_CHAR:
		pChan->putRcvChar	= callback;
		pChan->putRcvArg	= callbackArg;
		return OK;

	default:
		return ENOSYS;
	}
}











⌨️ 快捷键说明

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