📄 consolex.c
字号:
/* * This file contains the MVME162LX extended console IO package. * * This file was created originally by * On-Line Applications Research Corporation (OAR) * and modified by: * * Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN * * featuring support of: * * - Multi-SCC chip handling * - Non-blocking I/O (O_NDELAY flag in libc) * - Raw mode device (no CR/LF detection) * - RTS/CTS flow control * * REMARKS: This routine requires multiple interrupt vectors * from SCC_VECTOR (normaly 0x40) * to SCC_VECTOR+(number of SCC chips) * * The original copyright follows; * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. * * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. * EISCAT Scientific Association. M.Savitski * * This material is a part of the MVME162 Board Support Package * for the RTEMS executive. Its licensing policies are those of the * RTEMS above. * * $Id: consolex.c,v 1.8.8.1 2003/09/04 18:44:40 joel Exp $ */#define M162_INIT#include "consolex.h"#include <bsp.h>#include <rtems/libio.h>#include <stdio.h>#include <string.h>#include <ctype.h>#define NPORTS 4 /* Number of ports */#define DEVICEPREFIX "tty"#define RAWDEVICEPREFIX "rtty"#define CONSOLEPORT 0 /* port# of console: undef this if you do not want /dev/console */#define READRETRY 1 /* Maximum retry count for read one char */#define WRITERETRY 8 /* Maximum retry count for write one char */#define PORTFROM 0 /* for debug */static unsigned char opencount[NPORTS];/*********************************************************************** Ring buffer for device ***********************************************************************/#define QUEUE_LENGTH 128 /* Must be 2^n number */typedef struct { char buffer[QUEUE_LENGTH]; volatile int head; volatile int tail;} ReceiverBuffer;#define ReceiverBufferInitialize( _buffer ) \ do { \ (_buffer)->head = (_buffer)->tail = 0; \ } while ( 0 ) #define ReceiverBufferIsEmpty( _buffer ) \ ( (_buffer)->tail == (_buffer)->head )#define ReceiverBufferIsNearEmpty( _buffer ) \ ( (_buffer)->tail == (((_buffer)->head + 3) & (QUEUE_LENGTH-1)) )#define ReceiverBufferIsFull( _buffer ) \ ( (_buffer)->head == (((_buffer)->tail + 1) & (QUEUE_LENGTH-1)) )#define ReceiverBufferIsNearFull( _buffer ) \ ( (_buffer)->head == (((_buffer)->tail + 3) & (QUEUE_LENGTH-1)) )#define ReceiverBufferAdd( _buffer, _ch ) \ do { \ rtems_unsigned32 isrlevel; \ \ rtems_interrupt_disable( isrlevel ); \ (_buffer)->tail = ((_buffer)->tail+1) & (QUEUE_LENGTH-1); \ (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \ rtems_interrupt_enable( isrlevel ); \ } while ( 0 ) #define ReceiverBufferRemove( _buffer, _ch ) \ do { \ rtems_unsigned32 isrlevel; \ \ rtems_interrupt_disable( isrlevel ); \ (_buffer)->head = ((_buffer)->head+1) & (QUEUE_LENGTH-1); \ (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \ rtems_interrupt_enable( isrlevel ); \ } while ( 0 ) /*********************************************************************** DEVICE DEPENDED PART ***********************************************************************//* Time constant parameters CAUTION: These parameters are for MVME162LX-213 board. */#define TC38400 0x0006#define TC19200 0x000e#define TC9600 0x001e/* Re-defining SCC register control macros to support Multi SCC chips */#undef scc#if defined(mvme162lx)static scc_regs *scc[NPORTS] = { ((scc_regs * const) 0xFFF45004), ((scc_regs * const) 0xFFF45000), ((scc_regs * const) 0xFFF45804), ((scc_regs * const) 0xFFF45800)};#else/* XXX fix me */#warning "MVME162 BSP -- unknown address for SCC's"static scc_regs *scc[NPORTS] = { ((scc_regs * const) 0xFFF45004), ((scc_regs * const) 0xFFF45000), ((scc_regs * const) 0xFFF45804), ((scc_regs * const) 0xFFF45800)};#endif#undef ZWRITE0#define ZWRITE0(port, v) (scc[port]->csr = (unsigned char)(v))#undef ZREAD0#define ZREAD0(port) (scc[port]->csr)#undef ZREAD#define ZREAD(port, n) (ZWRITE0(port, n), (scc[port]->csr))#undef ZREADD#define ZREADD(port) (scc[port]->csr=0x08, scc[port]->csr )#undef ZWRITE#define ZWRITE(port, n, v) (ZWRITE0(port, n), ZWRITE0(port, v))#undef ZWRITED#define ZWRITED(port, v) (scc[port]->csr = 0x08, \ scc[port]->csr = (unsigned char)(v))static ReceiverBuffer receiverBuffer[NPORTS];/* * Control flags (DTR/DCD/RTS/CTS) */static unsigned char wr4[NPORTS];static unsigned char wr5[NPORTS];#define SCCSetDTR(port) ZWRITE(port, 5, (wr5[port] |= 0x80))#define SCCResetDTR(port) ZWRITE(port, 5, (wr5[port] &= ~0x80))#define SCCSetRTS(port) ZWRITE(port, 5, (wr5[port] |= 0x02))#define SCCResetRTS(port) ZWRITE(port,5, (wr5[port] &= ~0x02))#define SCCGetDCD(port) (ZREAD0(port)&0x08)#define SCCGetCTS(port) (ZREAD0(port)&0x20)/* * Interrupt handler for receiver interrupts */static rtems_isr SCCReceiverISR(rtems_vector_number vector){ register int ipend, port; port = (vector-SCC_VECTOR)*2; ZWRITE0(port, 0x38); /* reset highest IUS */ ipend = ZREAD(port, 3); /* read int pending from A side */ if(ipend == 0x04) port++; /* channel B intr pending */ else if(ipend == 0x20) ; /* channel A intr pending */ else return; ReceiverBufferAdd(&receiverBuffer[port], ZREADD(port)); if(ZREAD(port,1) & 0x70){ /* check error stat */ ZWRITE0(port, 0x30); /* reset error */ } if(ReceiverBufferIsNearFull(&receiverBuffer[port])) SCCResetRTS(port);}/* * Initialize */void SCCInitialize(){ int i; for(i = PORTFROM; i < NPORTS; i+=2) ZWRITE(i, 9,0xc0); /* Reset SCC Chip */ for(i = PORTFROM; i < NPORTS; i++){ ReceiverBufferInitialize(&(receiverBuffer[i])); wr4[i] = 0x44; ZWRITE(i, 4, wr4[i]); /* x16 clock, 1 stop, parity none */ ZWRITE(i, 1, 0); /* disable interrupts */ ZWRITE(i, 2, SCC_VECTOR+(i/2)); ZWRITE(i, 3, 0xc1); /* receiver enable, 8bits */ wr5[i] = 0x68; ZWRITE(i, 5, wr5[i]); /* transmitter enable, 8bits, DTR&RTS off */ ZWRITE(i,14, 0); /* stop baudrate gen. */ ZWRITE(i,11,0x50); /* use baurate gen. */ ZWRITE(i,15, 1); /* Select WR7' */ ZWRITE(i, 7, 0); /* Disable all special interrupts */ ZWRITE(i,10, 0); ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */ set_vector(SCCReceiverISR, SCC_VECTOR+(i/2), 1); /* install ISR */ ZWRITE(i, 9, 8); /* master interrupt enable */ ZWRITE(i,12,TC38400&0xff); /* set 38400 baud */ ZWRITE(i,13,TC38400>>8); ZWRITE(i,14, 3); /* start baudrate gen. */ /* CAUTION: If your SCC use XTAL on RTxC, write 1 */ } mcchip->vector_base = 0; mcchip->gen_control = 2; /* MIEN */ mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */}/* * Non-blocking char input */rtems_boolean SCCGetOne(int port, char *ch){ int retry = READRETRY; while(ReceiverBufferIsEmpty(&receiverBuffer[port])) if(--retry <= 0) return FALSE; ReceiverBufferRemove(&receiverBuffer[port],*ch); if(ReceiverBufferIsNearEmpty(&receiverBuffer[port])) SCCSetRTS(port); return TRUE;}/* * Blocking char input */char SCCGetOneBlocked(int port){ unsigned char tmp_char; while (!SCCGetOne(port, &tmp_char)) rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); return tmp_char;}/* * Non-blocking char input * No longer supports XON/XOFF flow control. */rtems_boolean SCCSendOne(int port, char ch){ int retry = WRITERETRY; if(!SCCGetCTS(port)) return FALSE; while(!(ZREAD0(port) & TX_BUFFER_EMPTY)) if(--retry <= 0) return FALSE; ZWRITED(port, ch); return TRUE;}/* * Blocking char output * No longer supports XON/XOFF flow control. */void SCCSendOneBlocked(int port, char ch){ while(!SCCSendOne(port, ch)) rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);}/* * Set parameters for transmission */unsigned32 SCCSetAttributes(int port, struct termios *t){ unsigned char wr3; ZWRITE(port,1,0); /* Disable interrupt */ ZWRITE(port,3,0); /* Disable receiver */ /* Baud */ switch(t->c_cflag & CBAUD){ case B38400: ZWRITE(port,12,TC38400&0xff); ZWRITE(port,13,TC38400>>8); break; case B19200: ZWRITE(port,12,TC19200&0xff); ZWRITE(port,13,TC19200>>8); break; case B9600: ZWRITE(port,12,TC9600&0xff); ZWRITE(port,13,TC9600>>8); break; } /* Code size */ wr5[port] &= 0x8f; wr3 = 0; /* receiver control */ switch(t->c_cflag & CSIZE){ case CS8: wr5[port] |= 0x60; wr3 |= 0xc0; break; case CS7: wr5[port] |= 0x20; wr3 |= 0x40; break; } /* Parity */ wr4[port] &= 0xf0; if(t->c_cflag & PARENB) wr4[port] |= 0x01; if(!(t->c_cflag & PARODD)) wr4[port] |= 0x02; /* ZWRITE(port,4,wr4[port]);*/ /* Stop bits */ /* wr4[port] = ZREAD(port,4) & 0xfc;*/ if(t->c_cflag & CSTOPB) wr4[port] |= 0x0c; else wr4[port] |= 0x04; ZWRITE(port,4,wr4[port]); /* TxRx parameters */ ZWRITE(port,5,wr5[port]); /* Transmission parameters */ ZWRITE(port,3,wr3|0x01); /* Enable receiver */ ZWRITE(port,1,0x10); /* Enable interrupt */ return 0;}/* * Get parameters for transmission */unsigned32 SCCGetAttributes(int port, struct termios *t){ unsigned32 b; t->c_cflag = 0; /* Baud */ b = ZREAD(port,13); b <<= 8; b |= ZREAD(port,12); switch(b){ case TC38400: t->c_cflag |= B38400; break; case TC19200: t->c_cflag |= B19200; break; case TC9600: t->c_cflag |= B9600; break; } /* Code size */ /* wr = ZREAD(port,5);*/ t->c_cflag &= ~CSIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -