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

📄 ch16552s.c

📁 AMX操作系统源码
💻 C
字号:
/*	*************************************************		*/
/*	*						*		*/
/*	*	AMX 4-Thumb Multitasking Kernel		*		*/
/*	*	ST16C552 DUART Serial I/O Support	*		*/
/*	*						*		*/
/*	*************************************************		*/
/*									*/
/*	Copyright (c) 1997						*/
/*	KADAK Products Ltd.						*/
/*	Vancouver, B.C., Canada						*/
/*									*/
/*	All rights reserved.						*/
/*									*/
/*  This document and source file contains CONFIDENTIAL INFORMATION	*/
/*  or trade secrets, or both, which are the property of KADAK		*/
/*  Products Ltd. This document and source file is subject to the	*/
/*  terms and conditions of the KADAK Products Ltd. Software License	*/
/*  Agreement which restricts the manner in which it may be used.	*/
/*									*/
/*	Release Date:	November 1, 1997				*/

#include	"cjzzz.h"		/* General Kernel definitions	*/

/* Configured for use on the ARM Development Board (ARM7TDMI)		*/
/*									*/
/*----------------- start modifications --------------------------------*/
/* All device dependent code sequences are indicated in this manner.	*/
/*----------------- end modifications ----------------------------------*/

/* ---------------------------------------------------------------------*/
/*----------------- start modifications --------------------------------*/
/* ARM Development Board (ARM7TDMI) definitions				*/

#define CLKRATE 1843200L	/* DUART clock input frequency = 1.8432Mhz*/

				/* Base address of ST16C552 chip	*/
#define VVCONPA 0x0D800000L	/* DUART channel A			*/
#define VVCONPB 0x0D800020L	/* DUART channel B			*/
#define VVDEBUG 1		/* Connector preferred for debugging	*/
				/* (1 = channel A; 2 = channel B)	*/
#define SCALE	4		/* Registers are word-aligned		*/

#define IOADR(base, reg)	((base) + (SCALE * (reg)))

/* The following macros are used for device input/output operations.	*/
/* Revise these macros, if necessary, to account for the manner in	*/
/* which devices are addressed in your hardware configuration.		*/

#define VVIODELAY 5		/* I/O delay needed (microseconds)	*/

#define IN8(port) \
	((VVIODELAY ? (cjcfhwdelay(VVIODELAY), 0) : 0), \
	(*((volatile unsigned char *)(port))))
#define OUT8(port, val) \
	((VVIODELAY ? (cjcfhwdelay(VVIODELAY), 0) : 0), \
	(*((volatile unsigned char *)(port)) = (unsigned char)(val)))
/*----------------- end modifications ----------------------------------*/

/* ---------------------------------------------------------------------*/
/* ST16C552 DUART register definitions					*/

#define RBR 0			/* Receive Buffer Register		*/
#define THR 0			/* Transmitter Holding Register		*/
#define IER 1			/* Interrupt Enable Register		*/
#define IIR 2			/* Interrupt Identification Register	*/
#define LCR 3			/* Line Control Register		*/
#define MCR 4			/* Modem Control Register		*/
#define LSR 5			/* Line Status Register			*/
#define MSR 6			/* Modem Status Register		*/
#define DLL 0			/* Divisor Latch LSB (DLAB = 1)		*/
#define DLM 1			/* Divisor Latch MSB (DLAB = 1)		*/

				/* Modem Control bit masks		*/
#define MCDTR	0x01			/* DTR				*/
#define MCRTS	0x02			/* RTS				*/
#define MCOUT1	0x04			/* Out 1 pin			*/
#define MCOUT2	0x08			/* Out 2 pin			*/

				/* Modem Status bit masks		*/
#define MSDSR	0x20			/* DSR				*/
#define MSCTS	0x10			/* CTS				*/

				/* Line Control bit masks		*/
/*----------------- start modifications --------------------------------*/
#define LCVAL	0x03			/* 8 data, 1 stop, no parity	*/
/*----------------- end modifications ----------------------------------*/
#define LCDLAB	0x80			/* Baud divisor program latch	*/

				/* Line Status bit masks		*/
#define LSDR	0x01			/* Data ready			*/
#define LSERR	0x0E			/* Receive error		*/
#define LSTHRE	0x20			/* Transmit hold reg empty	*/
#define LSTEMT	0x40			/* Transmit shift reg empty	*/

				/* Dummy needed to eliminate effects	*/
				/* of optimization by some compilers	*/
static void chdummy(unsigned char dummy) {}

/* ---------------------------------------------------------------------*/
/* Simple serial I/O device						*/

/* Logical port = 0 or 1 = debug or application				*/
#if (VVDEBUG == 1)
#define VVUSER VVCONPB
#define VVHOST VVCONPA
#else
#define VVUSER VVCONPA
#define VVHOST VVCONPB
#endif

/* Define commands and status						*/

#define CONCFGR	(0)		/* Initialize port (param = baud rate)	*/
#define CONSTAT	(1)		/* Read status register (param = unused)*/
#define CONREAD	(2)		/* Read from data register (param = unused)*/
#define CONWRITE (3)		/* Write to data register (param = char)*/

#define CONRRDY	(0x01) 		/* Character ready			*/
#define CONWRDY	(0x20)		/* Ready to write			*/

/* chuart - General DUART Support					*/
/*									*/

int CJ_CCPP chuart(
	int	port,				/* Logical port		*/
	int	opcode,				/* Opcode (see defs)	*/
	int	param)				/* Operation parameter	*/
{
	unsigned long base;
	unsigned char hwstatus;
	unsigned long baud;
	int	status;

/* Convert logical port to a physical port address			*/
	if (port == 0)
		base = VVHOST;
	else if (port == 1)
		base = VVUSER;

	else	return(-1);

	status = 0;
	switch (opcode) {
	case CONCFGR:			/* param = baud rate code	*/
				/* Baud divisor calculation:		*/
				/*		    input frequency	*/
				/* baud divisor = -------------------	*/
				/*			baud * 16	*/
		baud = CLKRATE;
		baud = baud / (param ? (unsigned long)param : 9600L);
		baud >>= 3;
		baud = (baud >> 1) + (baud & 1);  /* Round up		*/
		baud &= 0xFFFFL;


/*----------------- start modifications --------------------------------*/
					/* Set new DUART context	*/
					/* Prep for baud divisor	*/
		OUT8(IOADR(base, LCR), LCVAL + LCDLAB);
		OUT8(IOADR(base, DLL), baud & 0xFF);
		OUT8(IOADR(base, DLM), baud >> 8);
		OUT8(IOADR(base, LCR), LCVAL);	/* 8 data, 1 stop bit	*/
		OUT8(IOADR(base, IER), 0L);	/* Polled mode		*/
						/* Set DTR, RTS		*/
		OUT8(IOADR(base, MCR), MCDTR | MCRTS);

						/* Clear receiver	*/
		chdummy(IN8(IOADR(base, LSR)));
		chdummy(IN8(IOADR(base, RBR)));
		chdummy(IN8(IOADR(base, RBR)));
		chdummy(IN8(IOADR(base, RBR)));
/*----------------- end modifications ----------------------------------*/
		break;

	case CONSTAT:				/* param unused		*/
		hwstatus = IN8(IOADR(base, LSR));
		if (hwstatus & LSDR)
			status |= CONRRDY;	/* Character ready	*/
		if (hwstatus & LSTHRE)
			status |= CONWRDY;	/* Transmit ready	*/
		break;

	case CONWRITE:				/* param = character	*/
		while ( (IN8(IOADR(base, LSR)) & LSTHRE) == 0)
			;
		OUT8(IOADR(base, THR), param);
		break;

	case CONREAD:				/* param unused		*/
		while ( (IN8(IOADR(base, LSR)) & LSDR) == 0)
			;
		status = (int)IN8(IOADR(base, RBR));
		break;
	        
	default:
		break;
		}

	return(status);			/* Return status		*/
	}

/* End of File */

⌨️ 快捷键说明

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