/************************************************************/ /* Spidcom Technologies FILE NAME : uart.c DESCRIPTION : UART 16550 driver interface HISTORY : -------------------------------------------------------------- DATE | AUTHOR | Version | Description -------------------------------------------------------------- 4/02/04 | Glomeron | 1.0 | Creation */ /************************************************************/ #include #include "platform.h" #include "uart_dev.h" #include "uart_reg.h" #include "ioport.h" #include "uart.h" /* array of port information structures, see h_code.h for definition */ struct uart_dev pPortInfo[NUM_PORTS]; /* * coding of the allowed bit numbers (7,8) for the modified UART: * usage is code[n-7] where n=7,8 bits */ static const unsigned char code[] = { 2,3 }; /* baudrate <=> divisor */ static unsigned long BaudRate[] = { 50L, 75L, 110L, 134L, 150L, 300L, 600L, 1200L, 1800L, 2000L, 2400L, 3600L, 4800L, 7200L, 9600L, 19200L, 38400L, 57600L, 115200L, 0L }; /************************************************************************************** * * local modem functions: * **************************************************************************************/ /* modem is configured */ static INLINE void raise_dtr(struct uart_dev *dev) { unsigned short value_from_port; /* Read Modem Control Register */ value_from_port = inp(dev->baseAddress + MODEM_CONTROL_REGISTER); /* Output the Modem Control Register Value with */ /* the DTR bit activated */ outp(dev->baseAddress + MODEM_CONTROL_REGISTER, (value_from_port | 0x01) ); } /* modem is not configured */ static INLINE void drop_dtr(struct uart_dev *dev) { unsigned short value_from_port; /* Read Modem Control Register */ value_from_port = inp(dev->baseAddress + MODEM_CONTROL_REGISTER); /* Output the Modem Control Register Value with */ /* the DTR bit activated */ outp(dev->baseAddress + MODEM_CONTROL_REGISTER, (value_from_port | 0xFE) ); } /* terminal allowed to send */ static INLINE void raise_rts(struct uart_dev *dev) { unsigned short value_from_port; /* Read Modem Control Register */ value_from_port = inp(dev->baseAddress + MODEM_CONTROL_REGISTER); /* Output the Modem Control Register Value with */ /* the DTR bit activated */ outp(dev->baseAddress + MODEM_CONTROL_REGISTER, (value_from_port | 0x02) ); } /* terminal not allowaed to send more */ static INLINE void drop_rts(struct uart_dev *dev) { unsigned short value_from_port; /* Read Modem Control Register */ value_from_port = inp(dev->baseAddress + MODEM_CONTROL_REGISTER); /* Output the Modem Control Register Value with */ /* the DTR bit activated */ outp(dev->baseAddress + MODEM_CONTROL_REGISTER, (value_from_port | 0xFD) ); } /* toggle thre in IER to bounce the THRE interrupt */ static INLINE void bounce_thre(struct uart_dev *dev) { /* Disable THRE interrupt */ outp(dev->baseAddress + INTERRUPT_ENABLE_REGISTER,0x0D); /* Re-enable THRE interrupt */ outp(dev->baseAddress + INTERRUPT_ENABLE_REGISTER,0x0F); } /************************************************************************************** * * local ring functions: * RING_BUFFER_SIZE defined in uart_dev.h * **************************************************************************************/ /* init ring */ static INLINE void ring_init(struct ring *ring) { ring->rndx = 0; ring->wndx = 0; } /* get ring size */ static INLINE unsigned int ring_size(struct ring *ring) { return (ring->wndx+RING_BUFFER_SIZE-ring->rndx) & (RING_BUFFER_SIZE-1); } /* get ring remaining size */ static INLINE int ring_left(struct ring *ring) { return RING_BUFFER_SIZE-1-ring_size(ring); } /* is ring full? */ static INLINE int ring_full(struct ring *ring) { return ring_size(ring)==RING_BUFFER_SIZE-1; } /* is ring empty? */ static INLINE int ring_empty(struct ring *ring) { return ring_size(ring)==0; } /* add char to the ring */ static INLINE void ring_push(struct ring *ring, char c) { ring->buffer[ring->wndx] = c; ring->wndx = (ring->wndx+1)&(RING_BUFFER_SIZE-1); } /* pull char from the ring */ static INLINE char ring_pop(struct ring *ring) { char result; result = ring->buffer[ring->rndx]; ring->rndx = (ring->rndx+1)&(RING_BUFFER_SIZE-1); return result; } /******************************************************************************* * Function: receive_data_interrupt * Purpose: read data and put it in the rx_ring * Return: ******************************************************************************/ static void receive_data(struct uart_dev *dev) { char curChar; /* read the data. */ curChar = inp(dev->baseAddress + RECEIVE_REGISTER); /* store it in the buffer */ if(!ring_full(&dev->rx_ring)) { ring_push(&dev->rx_ring, curChar); } else { dev->stats.nb_rx_full++; } /* receive buffer buffer is full so handle_rx if requiered */ if(dev->handle_rx){ dev->handle_rx(dev->port); } } /******************************************************************************* * Function: transmit_data * Purpose: transmit the maximum possible data, assert FIFO is empty * Return: ******************************************************************************/ static void transmit_data(struct uart_dev *dev) { int i; char txChar; /* Transmit as many chars as port can handle */ for (i = 0; ((i < dev->maxTxChars) && !ring_empty(&dev->tx_ring)); i++) { /* Get next character to transmit and advance transmit data tail pointer. */ txChar = ring_pop(&dev->tx_ring); /* Transmit the character */ outp(dev->baseAddress + TRANSMIT_REGISTER, txChar); } } /******************************************************************************* * Function: update_modem_state * Purpose: update line modem status * Return: ******************************************************************************/ static void update_modem_state(struct uart_dev *dev) { register unsigned char valueFromPort; /* read port's modem status register */ valueFromPort =inp(dev->baseAddress + MODEM_STATUS_REGISTER); if (valueFromPort & MSR_DDSR) { /* Change in Data Set Ready */ if (valueFromPort & MSR_DSR){ /* DSR came on */ dev->dsrState = 1; } else { /* DSR went off */ dev->dsrState = 0; } } if (valueFromPort & MSR_DDCD) { /* Change In Data Carrier Detect */ if (valueFromPort & MSR_DCD) { /* DCD came on */ dev->dcdState = 1; } else { /* DCD went off */ dev->dcdState = 0; } } if (valueFromPort & MSR_DCTS) { /* Change in Clear To Send */ if (valueFromPort & MSR_CTS) { /* CTS came on */ dev->ctsState = 1; /* Generate a THRE IRQ to trigger data send */ bounce_thre(dev); } else { /* CTS went off */ dev->ctsState = 0; } } if (valueFromPort & MSR_TERI) { /* Change in Ring Indicator state */ if (valueFromPort & MSR_RI) { dev->stats.nb_ri++; } } } /******************************************************************************* * Function: update_error_stats * Purpose: update statistics for errors * Parameters: void * Return: ******************************************************************************/ static void update_error_stats(struct uart_dev *dev) { register unsigned char valueFromPort; /* Read Line Status Register */ valueFromPort = inp(dev->baseAddress + LINE_STATUS_REGISTER); /* Received 'break' */ if (valueFromPort & LSR_BI) dev->stats.nb_bi++; /* framing error */ if (valueFromPort & LSR_FE) dev->stats.nb_fe++; /* parity error */ if (valueFromPort & LSR_PE) dev->stats.nb_pe++; /* overrun error */ if (valueFromPort & LSR_OE) dev->stats.nb_oe++; } /******************************************************************************* * Function: uart_irq_handler * Purpose: handles interrupts for the UART0 * Parameters: void * Return: ******************************************************************************/ void uart_irq_handler(void *data) { register unsigned char valueFromPort; struct uart_dev *dev; char loop; /* get device from data */ dev=(struct uart_dev *)data; if(!dev) return; /* Loop until we make one complete pass w/out processing any interrupts */ do { /* Clear interrupts processed flag. */ loop = 0; /* Read Interrupt Identification Register */ valueFromPort = inp(dev->baseAddress + INTERRUPT_IDENT_REGISTER); if (valueFromPort & IIR_NO_INTERRUPT) { /* * If less than MAX_RCVFIFO characters have been * read without receiving a receive data * interrupt, check line status register to see * if there is still data in the FIFO. This code * will function correctly even if there isn't a FIFO. */ if (dev->nonIntChars < MAX_RCVFIFO) { /* Read another character */ /* Read the Line Status Register */ valueFromPort = inp(dev->baseAddress + LINE_STATUS_REGISTER); if (valueFromPort & LSR_DR) // Data is ready { /* * Increment number of chars processed from FIFO * without interrupt */ dev->nonIntChars++; /* Force at least one more pass through loop. */ loop = 1; /* read the data. */ receive_data(dev); } } } else /* an interrupt is pending */ { /* Set interrupts processed flag. */ loop = 1; /* Mask out unwanted bits from interrupt identification. */ valueFromPort &= INTERRUPT_IDENT_MASK; /* Conditional execution depending on type of interrupt */ switch (valueFromPort) { /* INTERRUPT Case: Receiver Line Status */ case (IIR_RECV_ERROR): /* keep a trace of errors */ update_error_stats(dev); /* read data */ receive_data(dev); break; /* INTERRUPT Case: Character Timeout */ case (IIR_CHAR_TMO): /* INTERRUPT Case: Received Data Available */ case (IIR_RECV_DATA): /* Check the Line Status Register to see if data is ready */ valueFromPort = inp(dev->baseAddress + LINE_STATUS_REGISTER); if ( !(valueFromPort & LSR_DR) ) break; /* * Set number of characters received without * data receive interrupt to 0. */ dev->nonIntChars = 0; /* read received data */ receive_data(dev); break; /* INTERRUPT Case: Transmit Holding Register Empty */ case (IIR_THRE): if (!ring_empty(&dev->tx_ring)) { /* Have data to transmit */ /* If port is using flow control . . . */ if (dev->obeyRtsCts && !dev->ctsState) { raise_rts(dev); } /* Read Line Status Register to clear */ /* interrupt condition. */ valueFromPort = inp(dev->baseAddress + LINE_STATUS_REGISTER); /* Make sure transmit holding register is really empty. */ if ( !(valueFromPort & LSR_THRE) ) break; /* Transmit as many chars as port can handle */ transmit_data(dev); } else { /* handle tx interrupt is requiered */ if(dev->handle_tx) { dev->handle_tx(dev->port); } /* If port is using flow control . . . */ if (dev->obeyRtsCts) { drop_rts(dev); } } break; /* INTERRUPT Case: Modem Status Change */ case (IIR_MODEM_STATUS): /* change modem status */ update_modem_state(dev); break; /* INTERRUPT Case: Unknown interrupt */ default: break; } /* switch */ } /* Interrupt pending */ } while (loop); return; } /************************************************************************************** * * uart_init: * initialize all uart devices, taht is uart0 and uart1 * **************************************************************************************/ int uart_init(void) { /* UART0 initialization */ pPortInfo[0].port=0; pPortInfo[0].baseAddress = UART0_BASE; // see tina_g.h pPortInfo[0].state=UART_INIT; outp(pPortInfo[0].baseAddress + INTERRUPT_ENABLE_REGISTER, 0x00); // disable UART0 IT /* UART1 initialization */ pPortInfo[1].port=1; pPortInfo[1].baseAddress = UART1_BASE; // see tina_g.h pPortInfo[1].state=UART_INIT; outp(pPortInfo[1].baseAddress + INTERRUPT_ENABLE_REGISTER, 0x00); // disable UART1 IT return 0; } /************************************************************************************** * * uart_set_param: * configure a particular parameter defined in uart.h * **************************************************************************************/ int uart_set_param(int port, int type, unsigned int value) { int i; struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_OPENED){ return -1; } switch(type) { case UART_BAUDRATE: for (i = 0; BaudRate[i] != 0L; i++) { if (value == BaudRate[i]) { break; } } if (BaudRate[i] == 0L) { return BAD_BR_DIVISOR; } dev->baudrate=value; /* divisor = INPUT_FREQ / OUTPUT_FREQ with OUTPUT_FREQ = 16 x baudrate */ dev->divisor = UART_INPUT_CLK / (16 * dev->baudrate); break; case UART_DATABITS: if((value < 7) || (value > 8)) { return BAD_NR_DATA_BITS_ARM; } dev->dataBits=(signed char)value; break; case UART_PARITY: if(value >3) { return BAD_PARITY; } dev->parity=(unsigned char)value; break; case UART_ADD_CR: dev->add_cr=value; break; case UART_STOPBITS: if ((value < 1) || (value > 2)) { return BAD_STOP_BITS; } dev->stopBits=(unsigned char)value; break; case UART_USEFIFO: dev->fifoEn=value; break; case UART_MAX_TXCHARS: /* Set maximum number of TX characters to transfer on FIFO empty */ if((value < 1) || (value > MAX_TRANFIFO)) { return BAD_TXFIFO_CHARS; } dev->maxTxChars=value; break; case UART_MAX_RXCHARS: switch (value) { case (1): case (4): case (8): case (14): break; default: return BAD_FIFO_TRIGGER_LEVEL; } dev->rxFifoTrigger=value; break; case UART_FLOWCONTROL: dev->obeyRtsCts=value; break; case UART_LOOPBACK: dev->loopbackEn=value; break; default: return BAD_PARAMETER; } return 0; } /************************************************************************************** * * uart_get_param: * get a particular parameter from device * **************************************************************************************/ int uart_get_param(int port, int type) { struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; switch(type) { case UART_BAUDRATE: return dev->baudrate; case UART_DATABITS: return dev->dataBits; case UART_PARITY: return dev->parity; case UART_STOPBITS: return dev->stopBits; case UART_USEFIFO: return dev->fifoEn; case UART_MAX_TXCHARS: return dev->maxTxChars; case UART_MAX_RXCHARS: return dev->rxFifoTrigger; case UART_FLOWCONTROL: return dev->obeyRtsCts; break; case UART_LOOPBACK: return dev->loopbackEn; default: return -1; } } /************************************************************************************** * * uart_set_tx_callback: * register a callback to be informed when the transmit circular buffer is empty * **************************************************************************************/ int uart_set_tx_callback(int port, handle_tx_t handle_tx) { struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_OPENED){ return -1; } /* register the callback */ dev->handle_tx=handle_tx; return 0; } /************************************************************************************** * * uart_set_rx_callback: * register a callback to be informed when the transmit circular buffer is empty * **************************************************************************************/ int uart_set_rx_callback(int port, handle_rx_t handle_rx) { struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_OPENED){ return -1; } /* register the callback */ dev->handle_rx=handle_rx; return 0; } /************************************************************************************** * * uart_open: * open one uart device identified by unit (Port): 0 or 1 * **************************************************************************************/ int uart_open(int port) { struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_INIT){ return -1; } dev->state=UART_OPENED; /* Initialize internal variables in port info entry */ ring_init(&dev->tx_ring); ring_init(&dev->rx_ring); dev->nonIntChars = 0; // stats: non interrupted chars due to FIFO /* set default parameters */ uart_set_param(port, UART_STOPBITS, 1); uart_set_param(port, UART_PARITY, 0); uart_set_param(port, UART_DATABITS, 8); uart_set_param(port, UART_BAUDRATE, 38400L); uart_set_param(port, UART_USEFIFO, 1); uart_set_param(port, UART_MAX_RXCHARS, 14); uart_set_param(port, UART_MAX_TXCHARS, 16); uart_set_param(port, UART_FLOWCONTROL, 0); uart_set_param(port, UART_LOOPBACK, 0); uart_set_param(port, UART_ADD_CR, 1); /* default mode is asynchronous */ uart_set_tx_callback(port, (handle_tx_t)0); uart_set_rx_callback(port, (handle_rx_t)0); return 0; } /************************************************************************************** * * uart_close: * close unit previously opened. * **************************************************************************************/ int uart_close(int port) { struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_OPENED){ return -1; } dev->state=UART_INIT; return 0; } /************************************************************************************** * * uart_start: * open one uart device identified by struct uart_dev * **************************************************************************************/ int uart_start(int port) { register unsigned short valueFromPort; unsigned char tmp; struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_OPENED){ return -1; } dev->state=UART_STARTED; /* * Initialize the Line Control Register * - divisor latch. * - parity, stopbits, databits... */ /* enable access to LCR register */ outp (dev->baseAddress + LINE_CONTROL_REGISTER, 0x80); /* - Set the low byte of the divisor latch */ outp (dev->baseAddress + DIV_LATCH_LOW_BYTE, dev->divisor & 0x00ff); /* - Set the high byte of the divisor latch */ outp (dev->baseAddress + DIV_LATCH_HIGH_BYTE, 0x00ff & ((dev->divisor & 0xff00) >> 8)); /* * - Set parity, data bits, and stop bits. * Also, disable writes to the divisor latch */ valueFromPort = ( ((dev->stopBits - 1) << 2) | (dev->parity << 3) | (code[dev->dataBits - 7]) ); outp (dev->baseAddress + LINE_CONTROL_REGISTER, valueFromPort); /* * Initialize the Modem Control Register * - Raise the OUT2 signal. * - Conditionally set loop-back mode (test) */ valueFromPort = 0x08; if (dev->loopbackEn) { valueFromPort |= 0x10; } outp (dev->baseAddress + MODEM_CONTROL_REGISTER, valueFromPort); /* * If port is not going to use hardware flow control, raise the Request * To Send signal and keep it on since some modems will not transmit * unless this signal is raised */ if (!dev->obeyRtsCts) { raise_rts(dev); } /* * Set interrupt enable registers to generate * interrupts for everything (i.e., Transmit * Holding Register Empty, Character Received, * Receive Error, and Modem Status Change) */ outp (dev->baseAddress + INTERRUPT_ENABLE_REGISTER, 0x0F); /* Clear interrupt identification register */ tmp = inp(dev->baseAddress + INTERRUPT_IDENT_REGISTER); /* Clear receive register */ tmp = inp(dev->baseAddress + RECEIVE_REGISTER); /* Clear line status interrupt */ tmp = inp(dev->baseAddress + LINE_STATUS_REGISTER); /* * Clear modem status interrupt and initialize modem * status signal flags */ valueFromPort = inp(dev->baseAddress + MODEM_STATUS_REGISTER); if (valueFromPort & MSR_CTS) dev->ctsState = 1; else dev->ctsState = 0; if (valueFromPort & MSR_DSR) dev->dsrState = 1; else dev->dsrState = 0; if (valueFromPort & MSR_DCD) dev->dcdState = 1; else dev->dcdState = 0; /* * If port is going to use TX and RX FIFOs flush transmit and receive FIFOs */ if (dev->fifoEn) { /* set the FIFO trigger depth */ switch (dev->rxFifoTrigger) { case (1): /* Enable the FIFO and set the RX FIFO trigger level to 1 */ outp(dev->baseAddress + FIFO_CONTROL_REGISTER, FCR_ENABLE_FIFO | FCR_RCV_TRIG_1 | FCR_FLUSH_XMIT_FIFO | FCR_FLUSH_RCV_FIFO); break; case (4): /* Enable the FIFO and set the RX FIFO trigger level to 4 */ outp(dev->baseAddress + FIFO_CONTROL_REGISTER, FCR_ENABLE_FIFO | FCR_RCV_TRIG_4 | FCR_FLUSH_XMIT_FIFO | FCR_FLUSH_RCV_FIFO); break; case (8): /* Enable the FIFO and set the RX FIFO trigger level to 8 */ outp(dev->baseAddress + FIFO_CONTROL_REGISTER, FCR_ENABLE_FIFO | FCR_RCV_TRIG_8 | FCR_FLUSH_XMIT_FIFO | FCR_FLUSH_RCV_FIFO); break; case (14): /* Enable the FIFO and set the RX FIFO trigger level to 14 */ outp(dev->baseAddress + FIFO_CONTROL_REGISTER, FCR_ENABLE_FIFO | FCR_RCV_TRIG_14 | FCR_FLUSH_XMIT_FIFO | FCR_FLUSH_RCV_FIFO); break; default: return BAD_FIFO_TRIGGER_LEVEL; } } else { /* Disable the FIFO */ outp(dev->baseAddress + FIFO_CONTROL_REGISTER, 0); } /* Turn on the Data Terminal Ready signal */ raise_dtr(dev); return 0; } /************************************************************************************** * * uart_stop: * hardware desactivation of the device. * **************************************************************************************/ int uart_stop(int port) { struct uart_dev *dev; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_STARTED){ return -1; } dev->state=UART_OPENED; /* disable all interrupts at UART level */ outp(dev->baseAddress + INTERRUPT_ENABLE_REGISTER, 0x00); return 0; } /******************************************************************************* * Function: uart_write * Description: attempt to write len bytes to the transmit ring. If ADD_CR * option is enabled, '\r' are inserted before each '\n'. If the buffer * hasn't enough space to put the len bytes, anly a part of the input buf * will be transfered. This function must be protected in synchronous mode * because the function can be interrupted before the return of the call. * Return: -1 if error, else return the number of bytes injected. ******************************************************************************/ void uart_write(int port, char * buf, int len, int *nbwritten) { register unsigned char valueFromPort; struct uart_dev *dev; char txChar; int escape; /* check port number */ if(port < 0 || port >= NUM_PORTS){ *nbwritten = -1; return; } dev=&pPortInfo[port]; /* check if unit at state started */ if(dev->state != UART_STARTED){ *nbwritten = -1; return; } escape = 0; *nbwritten = 0; /* fill transmit fifo buffer until maximum */ while (!escape && *nbwrittenadd_cr && buf[*nbwritten]=='\n') { if (ring_left(&dev->tx_ring)>=2) { ring_push(&dev->tx_ring, buf[(*nbwritten)++]); ring_push(&dev->tx_ring,'\r'); } else escape = 1; } else { if (!ring_full(&dev->tx_ring)) ring_push(&dev->tx_ring, buf[(*nbwritten)++]); else escape = 1; } } if(*nbwritten > 0) { /* if THR is empty, send one character manually to reset THRE pump */ valueFromPort=inp(dev->baseAddress + LINE_STATUS_REGISTER); if (valueFromPort & LSR_THRE) { /* If port is using flow control . . . */ if (dev->obeyRtsCts && !dev->ctsState) { raise_rts(dev); } txChar = ring_pop(&dev->tx_ring); /* Send character manually to reset THRE state machine */ outp(dev->baseAddress + TRANSMIT_REGISTER, txChar); } } } /******************************************************************************* * Function: uart_read * Purpose: reads len character from the receive buffer * Return: error message, data read, or data read and status * errors messages: * -1 = invalid device * else return the number of chars read ******************************************************************************/ int uart_read(int port, char *buf, int len) { struct uart_dev *dev; int escape, result; /* check port number */ if(port < 0 || port >= NUM_PORTS){ return -1; } dev=&pPortInfo[port]; /* check if unit at state opened */ if(dev->state != UART_STARTED){ return -1; } result = 0; escape = 0; while(!escape && resultrx_ring)) buf[result++] = ring_pop(&dev->rx_ring); else escape = 1; } return result; } #ifdef USE_UART_DUMP // not used from the bootloader; remove it /******************************************************************************* * Function: dumpUartParms * Purpose: print parameters used to initialize the UART * Parameters: void * Return: void ******************************************************************************/ int uart_dump(int port) { struct uart_dev *dev; if( (port < 0) || (port >= NUM_PORTS) ){ return -1; } dev=&pPortInfo[port]; printf("\nBase Address = %ld", dev->baseAddress); printf("\nBaud Rate = %ld",dev->baudrate); printf("\n# Data Bits = %d", dev->dataBits); printf("\nEnable Parity = %d", dev->parity); printf("\n# Stop Bits = %d", dev->stopBits); printf("\nRx Threshold = %d", dev->nonIntChars); printf("\nTx Threshold = %d", dev->maxTxChars); printf("\nRx FIFO Trigger = %d", dev->rxFifoTrigger); printf("\nEnable RTS/CTS = %d", dev->obeyRtsCts); printf("\nEnable FIFO's = %d", dev->fifoEn); printf("\nEnable Loopback = %d", dev->loopbackEn); return 0; } #endif // USE_UART_DUMP /******************************************************************************* * Function: uart_private_data * Purpose: return the private data for IRQ_Handler_Core * Parameters: port * Return: ******************************************************************************/ void *uart_private_data(int port) { return &pPortInfo[port]; }