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

📄 st16c554d.c

📁 1to4 usb hub μPD720114 ET-0191A 4端口自供电集线器原理图
💻 C
字号:
#include "st16c554d.h"
#include "2410addr.h"
#include "2410lib.h"
#include <string.h>

struct
{
	int sizes;
	unsigned char bufs[512];
}port_buffers[4];

void s3c2410_init_memory_control()
{
	//no need to set BWSCON, use default:8-bits bus,no wait,
	rBWSCON = rBWSCON & 0xff00f00f;
	
	rBANKCON1 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
	rBANKCON2 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
	rBANKCON4 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
	rBANKCON5 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
}
void s3c2410_reset_CS_pin()
{
	//set CS1,2,4,5 as cs pins
	rGPACON = rGPACON | 0x1b000;
}

void s3c2410_init_interrupt()
{
	//set gpf 0,1,2,3 as eint
	rGPFCON = (rGPFCON | 0xaa) & 0xffffffaa;
	
	//set the signaling method as high
	rEXTINT0 = (rEXTINT0 | 0x1111) & 0xffff1111;
	
	//set the signaling method as low
	//rEXTINT0 = rEXTINT0 & 0xfffff000;
	
	//set the signaling method as rising edge
	//rEXTINT0 = (rEXTINT0 | 0x4444) & 0xffff4444;
}

void st16c554_reset_chip()	//set PB0 as output
{
	rGPBCON = (rGPBCON & 0xfffffffd) | 0x01;
	//set PB0 high
	rGPBDAT = rGPBDAT | 0x01;
	//keep PB0 high for 40 ns to reset st16c554
	Delay(1);
	//set PB0 low
	rGPBDAT= rGPBDAT & 0xfffffffe;
}

//dtr:0,1 - force DTR# pin output high,low
//rts:0,1 - force RTS# pin output high,low
//intOutput:0,1 - INT(a-d) output disable(three state),INT(a-d) output enable(active)
void st16c554d_set_mcr(int port, int dtr, int rts, int intOutput)
{
	unsigned char *portAddr;
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}
	portAddr += rST16C554D_MCR;
	*portAddr = dtr | (rts << 1) | (intOutput << 3);

	Uart_Printf("%x=%x  ",portAddr,*portAddr);
}

//fifi:0,1 - disable,enalbe
//resetRxFifo:0,1 - not reset,reset
//resetTxFifo:0,1 - not reset,reset
//dma:0,1 - normal,dma mode
//RxTrigger:0,1,2,3 - 1,4,8,14
void st16c554d_set_fcr(int port, int fifo, int resetRxFifo, int resetTxFifo, int dma, int rxTrigger)
{
	unsigned char *portAddr;
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}
	portAddr += rST16C554D_FCR;
	*portAddr = fifo | (resetRxFifo << 1) | (resetTxFifo << 2) | (dma << 3)	| (rxTrigger << 6);

}

//worldLength:0,1,2,3 - 5,6,7,8 
//stopBit:0,1,1 - 1(5,6,7,8 bits length),1-1/2(5 bits length),2(6,7,8 bits length)
//parity: 0,1,3,5,7 - none,odd,even,forced 1,forced 0
void st16c554d_set_line(int port, int wordLength, int stopBit, int parity)
{
	unsigned char *portAddr;
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}
	portAddr += rST16C554D_LCR;
	*portAddr = wordLength | (stopBit << 2) | (parity << 3);
	Uart_Printf("%x=%x  ",portAddr,*portAddr);
	
}

//baud 200,1200,2400,4800,9600,19200,38400,76800,115200,230400,460800
void st16c554d_set_band(int port, int baud)
{
	unsigned char *portAddr;
	unsigned char dll = 0, dlm = 0;
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}
	
	switch(baud)
	{
		case 200:
			dlm = 0x09;	
			break;		
		case 1200:
			dlm = 0x01;
			dll = 0x80;
			break;
		case 2400:
			dll = 0xc0;
			break;
		case 4800:
			dll = 0x60;
			break;
		case 9600:
			dll = 0x30;
			break;
		case 19200:
			dll = 0x18;
			break;
		case 38400:
			dll = 0x0c;
			break;
		case 76800:
			dll = 0x06;
			break;
		case 115200:
			dll = 0x04;
			break;
		case 230400:
			dll = 0x02;
			break;
		case 460800:
			dll = 0x01;
			break;
		default:
			return;
	}
	
	//enalbe baudrate divisor
	*(portAddr + rST16C554D_LCR) = *(portAddr + rST16C554D_LCR) | 0x80;
	//write to dll and dlm
	*(portAddr + rST16C554D_DLL) = dll;
	*(portAddr + rST16C554D_DLM) = dlm;
	//disable baudrate divsior
	*(portAddr + rST16C554D_LCR) = *(portAddr + rST16C554D_LCR) & 0x7f;
	
}

void st16c554d_enable_irq(int port)
{
	unsigned char *portAddr;
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}
	portAddr += rST16C554D_IER;
	*portAddr = 0x01;
}

void st16c554d_disable_irq(int port)
{
	unsigned char *portAddr;
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}
	portAddr += rST16C554D_IER;
	*portAddr = 0x0;
}

void __irq st16c554_port_a_rx(void)
{
	int maxcount = 256;
	Uart_Printf("eint 0 occur!\n");
	//disable interrupt
	rINTMSK = rINTMSK | 1;
	ClearPending(BIT_EINT0);
	while (maxcount--)
	{
		if ((*( Add_st16c554d_portA + rST16C554D_LSR) & 0x01) == 0)
			break;
		port_buffers[0].bufs[port_buffers[0].sizes++] = *Add_st16c554d_portA;
	}
	//enable interrupt
	rINTMSK = rINTMSK & 0xfffffffe;
}

void __irq st16c554_port_b_rx(void)
{

	int maxcount = 256;
	//disable interrupt
	Uart_Printf("eint 1 occur!\n");
	rINTMSK = rINTMSK | 2;
	ClearPending(BIT_EINT1);
	while (maxcount--)
	{
		if ((*( Add_st16c554d_portB + rST16C554D_LSR) & 0x01) == 0)
			break;
		port_buffers[1].bufs[port_buffers[1].sizes++] = *Add_st16c554d_portB;
	}
	//enable interrupt
	rINTMSK = rINTMSK & 0xfffffffd;
	
}
void __irq st16c554_port_c_rx(void)
{
	int maxcount = 256;
	Uart_Printf("eint 2 occur!\n");
	//disable interrupt
	rINTMSK = rINTMSK | 4;
	ClearPending(BIT_EINT2);
	while (maxcount--)
	{
		if ((*( Add_st16c554d_portC + rST16C554D_LSR) & 0x01) == 0)
			break;
		port_buffers[2].bufs[port_buffers[2].sizes++] = *Add_st16c554d_portC;
	}

	//enable interrupt
	rINTMSK = rINTMSK & 0xfffffffb;
}
void __irq st16c554_port_d_rx(void)
{
	int maxcount = 256;
	Uart_Printf("eint 3 occur!\n");
	//disable interrupt
	rINTMSK = rINTMSK | 8;
	ClearPending(BIT_EINT3);
	while (maxcount--)
	{
		if ((*( Add_st16c554d_portD + rST16C554D_LSR) & 0x01) == 0)
			break;
		port_buffers[3].bufs[port_buffers[3].sizes++] = *Add_st16c554d_portD;
	}
	//enable interrupt
	rINTMSK = rINTMSK & 0xfffffff7;
}

void s3c2410_set_intmod(int port)
{
	 
}


void s3c2410_enable_irq(int port)
{
	unsigned int mskvalue;
	switch(port)
	{
		case 1:
			mskvalue = 0xfffffffe;
			break;
		case 2:
			mskvalue = 0xfffffffd;
			break;
		case 3:
			mskvalue = 0xfffffffb;
			break;
		case 4:
			mskvalue = 0xfffffff7;
			break;
		default:
			return;
	}
	rINTMSK = rINTMSK & mskvalue;
}

void s3c2410_disable_irq(int port)
{
	unsigned int mskvalue;
	switch (port)
	{
		case 1:
			mskvalue = 1;
			break;
		case 2:
			mskvalue = 2;
			break;
		case 3:
			mskvalue = 4;
			break;
		case 4:
			mskvalue = 8;
			break;
		default:
			return;
	}
	
	rINTMSK = rINTMSK | mskvalue;
}

void st16c554d_send_char(int port, unsigned char ch)
{
	unsigned char *portAddr;
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}
	while (!(*(portAddr + rST16C554D_LSR) & 0x20));
	*portAddr = ch;
}

void st16c554d_write(int port, char *source, int sizes)
{
	int i = 0,j,k,m;
	unsigned char *portAddr;
	
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return;
	}	
	
	j = sizes / 16;
	k = sizes % 16;
	
	for (m = 0; m < j; m++)
	{
		while (!(*(portAddr + rST16C554D_LSR) & 0x20));
		for (m = 0; m < 16; m++)
			*portAddr = *(source + i++);
	}
	
	while (!(*(portAddr + rST16C554D_LSR) & 0x20));
	for (m = 0; m < k; m++)
	{
		*portAddr = *(source + i++);
	}
}

int st16c554d_read(int port, unsigned char *dest)
{
	unsigned char *portAddr;
	int maxcount = 0;
	
	switch(port)
	{
		case 1:
			portAddr = Add_st16c554d_portA;
			break;
		case 2:
			portAddr = Add_st16c554d_portB;
			break;
		case 3:
			portAddr = Add_st16c554d_portC;
			break;
		case 4:
			portAddr = Add_st16c554d_portD;
			break;
		default:
			return 0;
	}	
	
	while ((*(portAddr + rST16C554D_LSR ) & 0x01) && (maxcount < 256)) 
	{
		*(dest + maxcount++) = *portAddr;
	}	
	return maxcount;
}

void Test_St16c554d_Uart(void)
{
	int i;
	int counter[4] = {0, 0, 0, 0};
	char string[][100] = {"hello,this demo string come from port A",
					      "hello,this demo string come from port B",
					      "hello,this demo string come from port C",
					      "hello,this demo string come from port D"};
	
	Uart_Printf("Reset St16c554 Test!\n");
	
	s3c2410_reset_CS_pin();
	
	s3c2410_init_interrupt();
	
	st16c554_reset_chip();
	
	Uart_Printf("Init 1,2,4,5 memory control bank!\n");
	s3c2410_init_memory_control();

	for (i = 0; i < 4; i++)
	{
		//disable interrupt
		s3c2410_disable_irq(i+1);
		//have to clear pengding interrupt
		ClearPending((1<<i));
		
		st16c554d_disable_irq(i+1);
		
		//clear buffer
		port_buffers[i].sizes = 0;
		memset(port_buffers[i].bufs,0,512);
		
		//baud 50,300,600,1200,2400,4800,9600,19200,38400,57600,115200
		st16c554d_set_band(i+1, 115200);
		
		//set moden control register
		//DTR#=high, RTS#=high, INT(a-d) output enable(active)
		st16c554d_set_mcr(i + 1, 0, 0, 1);
		
		//set fifo control register
		//enable fifo mode, reset thr, reset rhr, not dma mode, trigger level=1
		st16c554d_set_fcr(i+1, 1, 1, 1, 0, 0);	
		
		//set line control resiter
		//8 databits, 1 stopbit, none parity
		st16c554d_set_line(i+1, 3, 0, 0);
		
		Uart_Printf("\n____________________________\n");
	
	}
	
	Uart_Printf("rGPACON=%x,rBWSCON=%x, rBANKCON1=%x, rBANKCON2=%x, rBANKCON4=%x, rBANKCON5=%x\n",rGPACON,rBWSCON,rBANKCON1,rBANKCON2,rBANKCON4,rBANKCON5);
	Uart_Printf("MCRA=%x, LCRA=%x\n",*(Add_st16c554d_portA+rST16C554D_MCR),*(Add_st16c554d_portA+rST16C554D_LCR));
	Uart_Printf("MCRB=%x, LCRB=%x\n",*(Add_st16c554d_portB+rST16C554D_MCR),*(Add_st16c554d_portB+rST16C554D_LCR));
	Uart_Printf("MCRC=%x, LCRC=%x\n",*(Add_st16c554d_portC+rST16C554D_MCR),*(Add_st16c554d_portC+rST16C554D_LCR));
	Uart_Printf("MCRD=%x, LCRD=%x\n",*(Add_st16c554d_portD+rST16C554D_MCR),*(Add_st16c554d_portD+rST16C554D_LCR));

	pISR_EINT0 = (unsigned)st16c554_port_a_rx;
	pISR_EINT1 = (unsigned)st16c554_port_b_rx;
	pISR_EINT2 = (unsigned)st16c554_port_c_rx;
	pISR_EINT3 = (unsigned)st16c554_port_d_rx;
	
	for (i = 0; i < 4; i++)
	{
		st16c554d_enable_irq(i+1);
		s3c2410_enable_irq(i+1);
	}
	
	
	Uart_Printf("enable all interrupt!\n");
	 
	
	 while(1)
	 {
	 	for(i = 0; i < 4; i++)
	 	{
	 		if (port_buffers[i].sizes)
	 		{
	 			port_buffers[i].bufs[port_buffers[i].sizes] = '\0';
	 			Uart_Printf("%s\n",port_buffers[i].bufs);
	 			port_buffers[i].sizes = 0;
	 			memset(port_buffers[i].bufs,0,512);
	 		}
	 		
	 		//port_buffers[i].sizes = st16c554d_read(i,port_buffers[i].bufs);
	 		//if (port_buffers[i].sizes)
	 		//{
	 		//	port_buffers[i].bufs[port_buffers[i].sizes] = '\0';
	 		//	Uart_Printf("%s\n", port_buffers[i].bufs);
	 		//}
	 		
	 		if (counter[i] > 5000000)
	 		{
	 			st16c554d_write(i + 1, string[i], strlen(string[i]));
	 			//Uart_Printf("%s", string[i]);
	 			counter[i] = 0;
	 		}
	 		else
	 			counter[i]++;
	 	}
	 }
}

⌨️ 快捷键说明

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