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

📄 st16c554.c

📁 S3C44B0扩展16C554串口
💻 C
字号:
/*
; File: sample.c Package:UART init
; This is a sample code to show how to initialize the UART series of chips
; from Startech Semiconductors.
; This also includes some basic external loop back thru’ two different
; ports using the FIFO capability.
; This also includes external loop back thru a different computer
*/
//#include <stdio.h>
//#include <string.h>
//#include <fcntl.h>

//#include "..\inc\st16c554.h"

#include <string.h>
#include "..\inc\option.h"
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\cache.h"
#include "..\inc\uart.h"
#include "..\inc\power.h"
#include "..\inc\dma.h"
#include "..\inc\timer.h"
#include "..\inc\rtc.h"
#include "..\inc\etc.h"
#include "..\inc\iic.h"
#include "..\inc\stop.h"
#include "..\inc\extdma.h"
#include "..\inc\tp.h"
#include "..\inc\usb.h"
#include "..\inc\kb.h"
#include "..\inc\Pwm.h"
#include "..\inc\led.h"
#include "..\inc\lcd.h"
#include "..\inc\lcdlib.h"
#include "..\inc\44blcd.h"
#include "..\inc\slib.h"


#define UART_CLK 1843200.0

#define TRUE 1
#define FALSE 0
/* These are the various offsets for the registers inside the chip */
#define RHR 0x00 /* Receive Holding Register */
#define THR 0x00 /* Receive Holding Register */
#define IER 0x01 /* Interrupt Enable Register */
#define FCR 0x02 /* FIFO control Register */
#define ISR 0x02 /* Interrupt Status Register */
#define LCR 0x03 /* Line control register */
#define MCR 0x04 /* Modem Control Register */
#define LSR 0x05 /* Line Status Register */
#define MSR 0x06 /* Modem Status Register */
#define SCR 0x07 /* Scratch pad Register */
/* This two offsets are used for defining the baud rate */
#define DIVLSB 0x00 /* Divisor LSB latch address */
#define DIVMSB 0x01 /* Divisor MSB Latch address */
/*\
* Program table for baud rate
* This represents the LSB and MSB divisor latch data
\*/
char baud_table[8][2] = {
	{ 0x80, 0x01 }, /* 300 */
	{ 0x60, 0x00 }, /* 1200 */
	{ 0x30, 0x00 }, /* 2400 */
	{ 0x0c, 0x00 }, /* 9600 */
	{ 0x06, 0x00 }, /* 19K */
	{ 0x03, 0x00 }, /* 38k */
	{ 0x02, 0x00 }, /* 56k */
	{ 0x01, 0x00 } /* 115k */
};

/* Baud Rates */
#define _COM_300_ 0
#define _COM_1200_ 1
#define _COM_2400_ 2
#define _COM_9600_ 3
#define _COM_19K_ 4
#define _COM_38K_ 5
#define _COM_56K_ 6
#define _COM_115K_ 7
/* Parity */
#define _COM_NOPARITY_ 0
#define _COM_ODDPARITY_ 1
#define _COM_EVENPARITY_ 2
/* Stopbits */
#define _COM_STOP1_ 0
#define _COM_STOP2_ 1
#define _COM_STOP1_5_ 1
/* word length */
#define _COM_CHR5_ 0
#define _COM_CHR6_ 1
#define _COM_CHR7_ 2
#define _COM_CHR8_ 3
/* word length */
#define _COM_FIFO1_ 0
#define _COM_FIFO4_ 1
#define _COM_FIFO8_ 2
#define _COM_FIFO14_ 3

// 引入 inportb和outportb汇编语言子程序声明
// 注意颠倒参数的前后顺序
void outportb(U32, U8);
void outportw(U32, U16);
void outportl(U32, U32);
U8  inportb(U32);
U16 inportw(U32);
U32 inportl(U32);

#define printf Uart_Printf

void Delay(int);

void Init_16c554(void)
{
	// 中断 INTA
	rPCONG &= ~ 0xc000;	// GPG7(INTA) input
	rPUPG |= 0x80;		// GPG7 pullup disable
	// 数据 D0-7
	rPCOND &= ~ 0xffff;	// GPD7-0(D7-0) input
	rPUPD |= 0xff;		// GPD7-0 pullup disable
	// 中断选择 INTSEL
	rPDATF |= 0x80;		// GPF7(INTSEL) = 1
	rPCONF &= ~ 0xc000;	// GPF7 output
	rPCONF |= 0x4000;
	rPUPF |= 0x80;		// GPF7 pullup disable
	// 复位 RESET 地址 A0-3
	rPDATE |= 0x8;		// GPE3(RESET) = 1
	rPCONE &= ~ 0xf3c0;	// GPE3 4 6 7 (RESET A0 A1 A2)output
	rPCONE |= 0x5140;
	rPUPE |= 0xd8;		// GPE3 4 6 7 pullup disable
	// 片选 -CSA -CSB -CSC -CSD 写选通 -IOW 读选通 -IOW
	rPDATC |= 0x3f0;	// GPC4-9(-CSA -CSB -CSC -CSD -IOW -IOR) = 1
	rPCONC &= ~ 0xfff00;	// GPC4-9 output
	rPCONC |= 0x55500;
	rPUPC |= 0x3f0;		// GPC4-9 pullup disable
	// 中断信号INTA INTB INTC INTD
	rPCONG &= ~0xff00;	// GPG4-7(INTA-D) input
	rPUPG |= 0xf0;		// GPG4-7 pullup disable
	
	// 复位延时100ms
	Delay(1000);
	// RESET = 0
	rPDATE &= ~ 0x8;
	Delay(1000);
	
/*
	rPCONB |= 0x200;	// 选择nGCS4
	rBANKCON4 = 0x3f00; // 0x2ff0; // 0x2b40;
	rBWSCON &= ~ 0x0f0000;
	
	rPDATG = 0x0c;	// GPG2(INTSEL)=1,GPG3(RESET)=1
	rPCONG = 0x50;	// GPG2 GPG3输出
	rPUPG &= ~0x0c;	// GPG2 GPG3上拉使能
	
	rPDATF = 0x08;	// GPF3(电源使能)=1
	rPCONF = 0x40;	// GPG3输出
//	rPUPF = 0xf7;	// GPG3上拉使能
	Delay(100);		// 延时10ms
	rPDATG &= ~0x08;// GPG3(RESET)=0
*/
/*
	rPDATG = 0x0c;	// GPG2(INTSEL)=1,GPG3(RESET)=1
	rPCONG = 0x50;	// GPG2 GPG3输出
	rPUPG &= ~0x0c;	// GPG2 GPG3上拉使能
	
	rPDATF = 0x08;	// GPF3(电源使能)=1
	rPCONF = 0x40;	// GPG3输出
//	rPUPF = 0xf7;	// GPG3上拉使能
	Delay(100);		// 延时10ms
	rPDATG &= ~0x08;// GPG3(RESET)=0

	
	rPDATC |= 0x30;
	rPDATC &= ~ 0xe0;
	rPCONC &= ~ 0x0ffc;
	rPCONC |= 0x554;
	rPUPC |= 0x3e;
	
	rPCOND &= ~ 0xffff;	// PGD0-7 Input
	rPUPD &= ~ 0xff;	// PGD0-7 Pullup
*/
}



// 向16C554 addr 寄存器写一个字节
uart_write(U8 port,U8 addr,U8 dat)
{
	U32 temp;
	// 地址换算到 GPE7 6 4
	temp = (addr & 0x6) << 5;
	temp |= (addr & 0x1) << 4;
	// 地址输出
	rPDATE &= ~ 0xd0;	// A2-0 = 0
	rPDATE |= temp;
	// 片选换算到 GPC4-7 (port 0-3)
	temp = ( 1 << ( 4 + port % 4));
	// 片选输出
	rPDATC &= ~ temp;
	// 数据输出
	rPDATD = dat;
	// 数据线方向改为输出
	rPCOND |= 0x5555;
	// nWE 输出低
	rPDATC &= ~ 0x100;
	// 延时
	Delay(1);
	// nWE nOE 输出高
	rPDATC |= 0x300;
	// 数据线方向改为输入
	rPCOND &= ~ 0xffff;
	// 片选失效
	rPDATC |= 0xf0;
}


// 从C554 addr 寄存器读一个字节
U8 uart_read(U8 port,U8 addr)
{
	U32 temp;
	// 地址换算到 GPE7 6 4
	temp = (addr & 0x6) << 5;
	temp |= (addr & 0x1) << 4;
	// 地址输出
	rPDATE &= ~ 0xd0;	// A2-0 = 0
	rPDATE |= temp;
	// 片选换算到 GPC4-7 (port 0-3)
	temp = ( 1 << ( 4 + port % 4));
	// 片选输出
	rPDATC &= ~ temp;
	// nOE 输出低
	rPDATC &= ~ 0x200;
	// 延时
	Delay(1);
	// 得到数据
	temp = rPDATD;
	// nWE nOE 输出高
	rPDATC |= 0x300;
	// 片选失效
	rPDATC |= 0xf0;
	return temp;
}

// 串口设置
// port 0-4 对应 A-D 4个串口
void uart_init(U8 port,U32 baud)
{
	// LCR7 = 1
	uart_write(port,LCR,0x80);
	// 波特率换算设置
	baud = UART_CLK / 16 / baud;
	uart_write(port,DIVLSB,baud);
	uart_write(port,DIVMSB,baud >> 8);
	// 8个数据位 1个停止位 无校验位
	uart_write(port,LCR,0x03);
	// 使能FIFO 和 中断
	uart_write(port,FCR,0x07);
	// 使能发送和接受中断
	uart_write(port,IER,0x01);
	// 使能串口中断
//	uart_write(port,MCR,0x08);
}


int uart_check(void)
{
	U8 i;
	Uart_Printf("Writing aah to scr(0x07)\n");
	uart_write(0,SCR,0xaa);
	i = uart_read(0,SCR);
	Uart_Printf("Reading back %2xh from scr(0x07)\n\n",i);
	if(i == 0xaa)
		return TRUE;
	else
		return FALSE;
}

void uart_loop(void)
{
	U8 tmp;
    while(1)
    {
    	if(uart_read(0,LSR) & 0x01)
    	{
    		tmp = uart_read(0,RHR);
    		Delay(1);
    		uart_write(0,THR,tmp);
    	}
    }
}

void uart_putch(U8 port,U8 ch)
{
	uart_write(port,THR , ch);
}




/*\
* This function checks the existence of a port.
* It is very simple. Take the port address then write to the scratch pad
* an the read it back. If the data read back the same as one that was
* written then return TRUE else return FALSE.
\*/
int
check_port(com_port)
int com_port;
{
	int i;
	U32 k = 0x8000000 + 0x10000 * com_port + SCR;
	printf("Checking for port %4xH\n",com_port);
	/* Write 1010 1010 (0xaa) to scratch pad*/
	printf("Writing AAH in %4xH\n",com_port);
	outportb(/*0x8000000 + 0x10000 * com_port + SCR*/ k , 0xaa);
	/* read it back. If it the same then return TRUE */

	outportb(0,0);

	i = inportb(/*com_port + SCR*/ k);
	printf("Read back %2xH from %4xH\n",i,com_port);
	if( i == 0xaa)
		return TRUE;
	else
		return FALSE;
}
/*\
* This is the work horse function which actually setups the UART.
* It needs to know every thing.
\*/
int
init_uart(port,baud,parity,data,stop,fifo,trigger)
int port,baud,parity,data,stop,fifo,trigger;
{
	char lcr_byte;
	/* Set divisor latch */
	outportb(0x8000000 + 0x10000 * port+LCR, 0x80) ;
	printf("Divisor Latch is %2xH %2xH (High Low)\n",
	baud_table[baud][1],baud_table[baud][0]);
	outportb(0x8000000 + 0x10000 * port+DIVLSB, baud_table[baud][0]) ;
	outportb(0x8000000 + 0x10000 * port+DIVMSB, baud_table[baud][1]) ;
	/* Reset to normal Programming */
	/* Program the lcr_byte for the above parameters */
	lcr_byte = 0x00;
	lcr_byte = data; /* Set the bit0 & bit1 for word length */
	lcr_byte |= stop << 3; /* Set the bit2 for stop bit */
	if(parity != _COM_NOPARITY_) {
		lcr_byte |= 1 << 4; /* Set the bit3 for parity */
		if(parity == _COM_EVENPARITY_)
		lcr_byte |= 1 << 5; /* Set the bit4 for EVEN parity */
	}
	printf("LCR byte is %2xH\n",lcr_byte);
	/* Program LCR */
	outportb(0x8000000 + 0x10000 * port+LCR, lcr_byte) ;
	if(fifo) {
		char fifo_byte;
		printf("Programming FIFOs without DMA mode\n");
		/* Have to first set the fifo enable */
		fifo_byte = 0x01;
		outportb(0x8000000 + 0x10000 * port+FCR,fifo_byte);
		/* Now program the FIFO */
		fifo_byte = 0x07; /* set bit0 - FIFO enable, Reset RCVR and XMIT FIFO */
		fifo_byte |= trigger << 7; /* set bit6 and bit7 with the trigger level */
		/* Program FCR */
		outportb(0x8000000 + 0x10000 * port+FCR,fifo_byte);
		if(~(inportb(0x8000000 + 0x10000 * port + ISR) & 0xc0)) {
			printf("This port %4xH does not have FIFOs\n");
			printf("Hence did not program Enable FIFOs\n");
		}
	}
	/* Program IER */
	printf("Programming IER for interrupt on bit0 RCV holding Register\n");
	outportb(0x8000000 + 0x10000 * port+IER, 0x01);
	return TRUE;
}

⌨️ 快捷键说明

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