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

📄 ns16550a.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
字号:
/*
 * File:		ns16550a.c
 * Purpose:		Device driver for the NS 16550a UART
 *
 * Notes:
 *
 * Author:		Eric DeVolder	devolder@oakhill.sps.mot.com
 * Date:		3-26-96
 *
 * Modifications:
 *
 */


#include "src/uif/dbug.h"
#include "ns16550a.h"

/***********************************************************/
void
ns16550a_init (NS16550A *ns16550a, int baud)
{
	/*
	 * This routine initializes the UART for the specified
	 * baud and NO interrupts.  It also does not enable
	 * the 16550 FIFOs.  (Basically a NS8250 mode device.)
	 */
	int divisor;

	switch (baud)
	{
		case 19200:
			divisor = BPS_19200;
			break;
		case 38400:
			divisor = BPS_38400;
			break;
#if (defined(MPC602_EVB))
		case 1200:
			divisor = BPS_1200;
			break;
#endif
		case 9600:
		default:
			divisor = BPS_9600;
			break;
	}

	/*
	 * Configure the device for 8N1 and also select the
	 * divisor latches so that divisor can be written to
	 * them.
	 */
	ns16550a->LCR = ( 0
		| EIGHT_DATA_NO_PARITY_ONE_STOP
		| LCR_DLAB
		) ;

	/*
	 * Write out the divisor.
	 */
	ns16550a->BR = (divisor & 0x000000FF);			/* DLLSB */
	ns16550a->IER = (divisor & 0x0000FF00) >> 8;	/* DLMSB */

#if (defined(MPC602_EVB) || defined(MPC602_EVB_NET))
	/*
	 * Put CLK on MF1, programmed in Alternate Function Register
	 */
	ns16550a->IIR = 0x02;
#endif

	/*
	 * Deselect the divisor latch.
	 */
	ns16550a->LCR = EIGHT_DATA_NO_PARITY_ONE_STOP;

	/*
	 * Make sure not in 16550 mode, and clear the FIFOs.
	 */
	ns16550a->IIR = 0;

	/*
	 * If a 16550 device, turn on the FIFO (but not the interrupts)
	 * so that data won't be lost.
	 */
	/* ns16550a->IIR =
		  FCR_FIFO_ENABLE
		| FCR_RCVR_FIFO_RESET
		| FCR_XMIT_FIFO_RESET
		;
	*/

	/*
	 * Make sure no interrupts generated.
	 */
	ns16550a->IER = 0
		| IER_ERBFI
		;

	/*
	 * Set modem control signals to desired state.
	 */
	ns16550a->MCR = 0;

	/*
	 * Clear any data which may be incorrectly accumulated.
	 */
	while (ns16550a->LSR & LSR_DATA_READY)
	{
		divisor = ns16550a->BR;
	}
}


/***********************************************************/
int
ns16550a_in_char (NS16550A *ns16550a)
{
	/*
	 * This routine polls the UART until a character is received.
	 */
	while (!(ns16550a->LSR & LSR_DATA_READY))
		;
	return ns16550a->BR;
}

/***********************************************************/
void
ns16550a_out_char (NS16550A *ns16550a, int c)
{
	/*
	 * This routine waits until the UART is ready to transmit, then
	 * transmits the character.
	 */
	while (!(ns16550a->LSR & LSR_THR_EMPTY))
		;
	ns16550a->BR = (BYTE)c;
}

/***********************************************************/
int
ns16550a_char_present (NS16550A *ns16550a)
{
	return (ns16550a->LSR & LSR_DATA_READY);
}

/***********************************************************/
int
ns16550a_device_present (NS16550A *ns16550a)
{
	/*
	 * This routine attempts to determine if the 16550a is
	 * present at the address pointed to by 'ns16550a'.
	 */

	/*
	 * 1)  Test general functionality of the register set.
	 */
	ns16550a->LCR = 0xAA;
	if (ns16550a->LCR != 0xAA)
	{
		return -1;
	}

	/*
	 * DLM when LCR[7] = 1.
	 */
	ns16550a->IER = 0x55;		/* DLM */
	if (ns16550a->IER != 0x55)
	{
		return -2;
	}

	ns16550a->LCR = 0x55;
	if (ns16550a->LCR != 0x55)
	{
		return -3;
	}

	ns16550a->IER = 0x55;
	if (ns16550a->IER != 0x05)
	{
		return -3;
	}

	ns16550a->IIR = 0x00;	/* FCR */
	ns16550a->IER = 0x00;
	if (ns16550a->IIR != 0x01)
	{
		return -4;
	}

	/*
	 * Test Modem Control registers.
	 */
	ns16550a->MCR = 0xf5;
	if (ns16550a->MCR != 0x15)
	{
		return -4;
	}

	ns16550a->MCR = 0x10;
	(void)ns16550a->MSR;
	if ((ns16550a->MSR & 0xF0) != 0x00)
	{
		return -5;
	}
	ns16550a->MCR = 0x1F;
	if ((ns16550a->MSR & 0xF0) != 0xF0)
	{
		return -6;
	}
	ns16550a->MCR = 0x03;

	/*
	 * Determine port type.
	 */
	ns16550a->SCR = 0x55;
	if (ns16550a->SCR != 0x55)
	{
		return 1;		/* NS8250 */
	}

	ns16550a->IIR = 0xCF;
	if ((ns16550a->IIR & 0xC0) != 0xC0)
	{
		return 2;		/* NS16450 */
	}
	ns16550a->IIR = 0x00;

	ns16550a->LCR = 0x80;
	ns16550a->IIR = 0x07;
	if (ns16550a->IIR != 0x07)
	{
		ns16550a->LCR = 0x00;
		return 3;		/* NS16550A */
	}
	
	ns16550a->IIR = 0x00;
	ns16550a->LCR = 0x00;
	return 4;		/* NS16C552 */
}

/***********************************************************/

⌨️ 快捷键说明

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