1/* 2 * serialGT.c 3 * 4 * BRIEF MODULE DESCRIPTION 5 * Low Level Serial Port control for use 6 * with the Galileo EVB64120A MIPS eval board and 7 * its on board two channel 16552 Uart. 8 * 9 * Copyright (C) 2000 RidgeRun, Inc. 10 * Author: RidgeRun, Inc. 11 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com 12 * 13 * This program is free software; you can redistribute it and/or modify it 14 * under the terms of the GNU General Public License as published by the 15 * Free Software Foundation; either version 2 of the License, or (at your 16 * option) any later version. 17 * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * You should have received a copy of the GNU General Public License along 30 * with this program; if not, write to the Free Software Foundation, Inc., 31 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 * 33 */ 34 35// Note: 36// Serial CHANNELS - 0 is the bottom connector of evb64120A. 37// (The one that maps to the "B" channel of the 38// board's uart) 39// 1 is the top connector of evb64120A. 40// (The one that maps to the "A" channel of the 41// board's uart) 42int DEBUG_CHANNEL = 0; // See Note Above 43int CONSOLE_CHANNEL = 1; // See Note Above 44 45#define DUART 0xBD000000 /* Base address of Uart. */ 46#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA 47 register set of the 16552 Uart device. 48 DUART+0 gets you to the ChanB register set. 49 */ 50#define DUART_DELTA 0x4 51#define FIFO_ENABLE 0x07 52#define INT_ENABLE 0x04 /* default interrupt mask */ 53 54#define RBR 0x00 55#define THR 0x00 56#define DLL 0x00 57#define IER 0x01 58#define DLM 0x01 59#define IIR 0x02 60#define FCR 0x02 61#define LCR 0x03 62#define MCR 0x04 63#define LSR 0x05 64#define MSR 0x06 65#define SCR 0x07 66 67#define LCR_DLAB 0x80 68#define XTAL 1843200 69#define LSR_THRE 0x20 70#define LSR_BI 0x10 71#define LSR_DR 0x01 72#define MCR_LOOP 0x10 73#define ACCESS_DELAY 0x10000 74 75/****************************** 76 Routine: 77 Description: 78 ******************************/ 79int inreg(int channel, int reg) 80{ 81 int val; 82 val = 83 *((volatile unsigned char *) DUART + 84 (channel * CHANNELOFFSET) + (reg * DUART_DELTA)); 85 return val; 86} 87 88/****************************** 89 Routine: 90 Description: 91 ******************************/ 92void outreg(int channel, int reg, unsigned char val) 93{ 94 *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET) 95 + (reg * DUART_DELTA)) = val; 96} 97 98/****************************** 99 Routine: 100 Description: 101 Initialize the device driver. 102 ******************************/ 103void serial_init(int channel) 104{ 105 /* 106 * Configure active port, (CHANNELOFFSET already set.) 107 * 108 * Set 8 bits, 1 stop bit, no parity. 109 * 110 * LCR<7> 0 divisor latch access bit 111 * LCR<6> 0 break control (1=send break) 112 * LCR<5> 0 stick parity (0=space, 1=mark) 113 * LCR<4> 0 parity even (0=odd, 1=even) 114 * LCR<3> 0 parity enable (1=enabled) 115 * LCR<2> 0 # stop bits (0=1, 1=1.5) 116 * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8) 117 */ 118 outreg(channel, LCR, 0x3); 119 120 outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */ 121 122 outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */ 123} 124 125/****************************** 126 Routine: 127 Description: 128 Set the baud rate. 129 ******************************/ 130void serial_set(int channel, unsigned long baud) 131{ 132 unsigned char sav_lcr; 133 134 /* 135 * Enable access to the divisor latches by setting DLAB in LCR. 136 * 137 */ 138 sav_lcr = inreg(channel, LCR); 139 140 /* 141 * Note: Set baud rate, hardcoded here for rate of 115200 142 * since became unsure of above "buad rate" algorithm (??). 143 */ 144 outreg(channel, LCR, 0x83); 145 outreg(channel, DLM, 0x00); // See note above 146 outreg(channel, DLL, 0x02); // See note above. 147 outreg(channel, LCR, 0x03); 148 149 /* 150 * Restore line control register 151 */ 152 outreg(channel, LCR, sav_lcr); 153} 154 155 156/****************************** 157 Routine: 158 Description: 159 Transmit a character. 160 ******************************/ 161void serial_putc(int channel, int c) 162{ 163 while ((inreg(channel, LSR) & LSR_THRE) == 0); 164 outreg(channel, THR, c); 165} 166 167/****************************** 168 Routine: 169 Description: 170 Read a received character if one is 171 available. Return -1 otherwise. 172 ******************************/ 173int serial_getc(int channel) 174{ 175 if (inreg(channel, LSR) & LSR_DR) { 176 return inreg(channel, RBR); 177 } 178 return -1; 179} 180 181/****************************** 182 Routine: 183 Description: 184 Used by embedded gdb client. (example; gdb-stub.c) 185 ******************************/ 186char getDebugChar() 187{ 188 int val; 189 while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in. 190 return (char) val; 191} 192 193/****************************** 194 Routine: 195 Description: 196 Used by embedded gdb target. (example; gdb-stub.c) 197 ******************************/ 198void putDebugChar(char c) 199{ 200 serial_putc(DEBUG_CHANNEL, (int) c); 201} 202