Esempio n. 1
0
static inline void set_dlf(struct device *dev, u32_t val)
{
	struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev);

	OUTBYTE(DLF(dev), val);
	dev_data->dlf = val;
}
Esempio n. 2
0
static void set_baud_rate(struct device *dev, uint32_t baud_rate)
{
	struct uart_device_config * const dev_cfg = DEV_CFG(dev);
	struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev);
	uint32_t divisor; /* baud rate divisor */

	if ((baud_rate != 0) && (dev_cfg->sys_clk_freq != 0)) {
		/* calculate baud rate divisor */
		divisor = (dev_cfg->sys_clk_freq / baud_rate) >> 4;

		/* set the DLAB to access the baud rate divisor registers */
		OUTBYTE(LCR(dev), LCR_DLAB);
		OUTBYTE(BRDL(dev), (unsigned char)(divisor & 0xff));
		OUTBYTE(BRDH(dev), (unsigned char)((divisor >> 8) & 0xff));

		dev_data->baud_rate = baud_rate;
	}
Esempio n. 3
0
/* Temporarily disable the transmit interrupt.  Called when there is not
any more data queued up to send.*/
void uart_hw_disable_tx_int(PUART_INFO uinfo)
{
#if (UART_16550)
    OUTBYTE(uinfo->port_base + IER, THRE_OFF); io_delay();

#else
#error: Implement disabling uart tx interrupts
#endif
}
Esempio n. 4
0
/* Queue up some data to send.  This is only called when uart_hw_poll_tx
returns true, which means that there is some space in the UART to hold some
data.  Therefore, this routine does not need to check the uart to see if data
can be written, because uart_hw_poll_tx has been called. */
void uart_hw_tx(PUART_INFO uinfo, byte data)
{
#if (UART_16550)
    OUTBYTE(uinfo->port_base + THR, data); io_delay();

#else
#error: Implement sending data over uart
#endif
}
Esempio n. 5
0
/* Implement this only if you will have handshaking capability in your UART.
 If you won't, then turn off UART_SUPPORTS_HANDSHAKING for your target.
 This function is 
 */
void uart_hw_enable_sender(PUART_INFO uinfo)
{
#if (UART_16550)
DEBUG_ERROR("ENABLE SENDER", NOVAR, 0, 0);
    OUTBYTE(uinfo->port_base + MCR, INBYTE(uinfo->port_base + MCR) | RESUME_MASK); 
#else
#error Implement hw handshaking, rx enable, or turn off SUPPORTS_HANDSHAKING
#endif
}
Esempio n. 6
0
/* Enable the transmit interrupt.  Called when data is ready to be sent.
   This routine should be ISR safe. */
void uart_hw_enable_tx_int(PUART_INFO uinfo)
{
#if (UART_16550)
    if (!uinfo->is_16550 || !uinfo->xmit_on)
    {
#if (DEBUG_XMIT)
        DEBUG_ERROR("uart_hw_enable_tx_int: start xmit", NOVAR, 0, 0);
#endif

        /* Start tranmitting by toggling xmit reg empty in interrupt enable reg   */
        OUTBYTE(uinfo->port_base + IER, THRE_OFF);  /* THRE off */
        io_delay();
        OUTBYTE(uinfo->port_base + IER, THRE_ON);  /* THRE on */
        io_delay();
    }
#else
#error: Implement uart enable tx interrupts
#endif
}
Esempio n. 7
0
/* Completely turn off the uart.  No more interrupts should be generated
    or anything. Called by uart_close(). */
void uart_hw_disable(PUART_INFO uinfo)
{
    ks_disable();

#if (UART_16550)
    /* Mask off all uart interrupts   */
    OUTBYTE(uinfo->port_base + IER, 0);
#endif
    ks_enable();
}
Esempio n. 8
0
/* 16550 is done with a macro in uartport.h   */
void uart_hw_resume_sender(PUART_INFO uinfo)
{
#if (UART_16550)
    if (uinfo->handshake_mask)
    {
        OUTBYTE(uinfo->port_base + MCR, INBYTE(uinfo->port_base + MCR) | uinfo->resume_mask); 
        io_delay();
    }
#else
#error Implement hw handshaking, rx enable, or turn off SUPPORTS_HANDSHAKING
#endif
}
Esempio n. 9
0
void uart_hw_hold_off_sender(PUART_INFO uinfo)
{
#if (UART_16550)
    if (uinfo->handshake_mask) 
    {
DEBUG_ERROR("HOLD OFF SENDER", NOVAR, 0, 0);
        OUTBYTE(uinfo->port_base + MCR, INBYTE(uinfo->port_base + MCR) & uinfo->holdoff_mask ); 
        io_delay();
    }
#else
#error Implement hw handshaking, rx enable, or turn off SUPPORTS_HANDSHAKING
#endif
}
Esempio n. 10
0
int pcvid_putc(KS_CONSTANT char c)
{
PFBYTE p;

    pcvid_init_term(0);
    if(linewrap_flag && c!='\r' && c!='\n')
    {
        cursor_x=1;
        if(cursor_y<24)
        {
            cursor_y++;
        }
        else
        {
            pcvid_scroll_up();
        }
    }

    linewrap_flag=FALSE;

    if(c!='\t'&&c!='\b'&&c!='\n'&&c!='\r')
    {
        p = pvideo + (cursor_y*(PCVID_SCREEN_COLS*2)) + (cursor_x*2);
        *p++ = c;
        *p = 0x07;  /* white on black */
        cursor_x++;
    }
    else if(c=='\b')
    {
        if(cursor_x>0)
        {
            cursor_x--;
            p = pvideo + (cursor_y*(PCVID_SCREEN_COLS*2)) + (cursor_x*2);
            *p++ = ' ';
            *p = 0x07;  /* white on black */
        }
    } 
    else if(c=='\t')
    {
        cursor_x--;
        cursor_x+=8;
        cursor_x/=8;
        cursor_x*=8;
        cursor_x++;
    } 
    else if(c=='\r')
    {
        cursor_x=1;
    } 
    else if(c=='\n')
    {
        if(cursor_y<24)
        {
            cursor_y++;
        }
        else
        {
            pcvid_scroll_up();
        }
    }
    
    if(cursor_x>79)
    {
        cursor_x=0;
        linewrap_flag=TRUE;
    }

#if (!defined (DJGPP) )
    {
        union _REGS regs;
    
        /* put cursor at appropriate position   */
        regs.h.ah=2;
        regs.h.dl=(byte)cursor_x;
        regs.h.dh=(byte)cursor_y;
        regs.h.bh=0;
        _int86(0x10,&regs,&regs);
    }
#elif (AT_MOTHERBOARD && (IS_MS_PM || IS_BCC_PM || IS_WC_PM || IS_HC_PM))
    /*
     * [i_a] added code to update cursor position for any VGA/EGA/CGA or HGC
     * card IFF we can access the video hardware registers using I/O 
     * instructions. Maybe the condition above is a bit too restrictive, but
     * it works for them :-)
     */
    {
        unsigned int pos = cursor_y * PCVID_SCREEN_COLS + cursor_x;
                     
        if (pcvid_mode == 0)
        {             
            /*
                3d4h index  Eh (R/W):  CRTC: Cursor Location High Register
                bit 0-7  Upper 8 bits of the address of the cursor
                
                3d4h index  Fh (R/W):  CRTC: Cursor Location Low Register
                bit 0-7  Lower 8 bits of the address of the cursor
             */   
            OUTBYTE(0x3D4,0x0E);        
            OUTBYTE(0x3D5,pos >> 8);      
            OUTBYTE(0x3D4,0x0F);        
            OUTBYTE(0x3D5,pos);      
        }
        else 
        {             
Esempio n. 11
0
int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r)
{
    uInt j;			/* temporary storage */
    inflate_huft *t;		/* temporary pointer */
    uInt e;			/* extra bits or operation */
    uLong b;			/* bit buffer */
    uInt k;			/* bits in bit buffer */
    Bytef *p;			/* input data pointer */
    uInt n;			/* bytes available there */
    Bytef *q;			/* output window write pointer */
    uInt m;			/* bytes to end of window or read pointer */
    Bytef *f;			/* pointer to copy strings from */
    inflate_codes_statef *c = s->sub.decode.codes;	/* codes state */

    /* copy input/output information to locals (UPDATE macro restores) */
    LOAD

    /* process input and output based on current state */
	while (1)
	switch (c->mode)
	{			/* waiting for "i:"=input, "o:"=output, "x:"=nothing */
	    case START:	/* x: set up for LEN */
#ifndef SLOW
		if (m >= 258 && n >= 10)
		{
		    UPDATE
			r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
		    LOAD
			if (r != Z_OK)
		    {
			c->mode = r == Z_STREAM_END ? WASH : BADCODE;
			break;
		    }
		}
#endif /* !SLOW */
		c->sub.code.need = c->lbits;
		c->sub.code.tree = c->ltree;
		c->mode = LEN;
	    case LEN:		/* i: get length/literal/eob next */
		j = c->sub.code.need;
		NEEDBITS(j)
		    t = c->sub.code.tree + ((uInt) b & inflate_mask[j]);
		DUMPBITS(t->bits)
		    e = (uInt) (t->exop);
		if (e == 0)	/* literal */
		{
		    c->sub.lit = t->base;
		    Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
			     "inflate:         literal '%c'\n" :
			     "inflate:         literal 0x%02x\n", t->base));
		    c->mode = LIT;
		    break;
		}
		if (e & 16)	/* length */
		{
		    c->sub.copy.get = e & 15;
		    c->len = t->base;
		    c->mode = LENEXT;
		    break;
		}
		if ((e & 64) == 0)	/* next table */
		{
		    c->sub.code.need = e;
		    c->sub.code.tree = t + t->base;
		    break;
		}
		if (e & 32)	/* end of block */
		{
		    Tracevv((stderr, "inflate:         end of block\n"));
		    c->mode = WASH;
		    break;
		}
		c->mode = BADCODE;	/* invalid code */
		z->msg = (char *)"invalid literal/length code";
		r = Z_DATA_ERROR;
		LEAVE
	    case LENEXT:	/* i: getting length extra (have base) */
		j = c->sub.copy.get;
		NEEDBITS(j)
		    c->len += (uInt) b & inflate_mask[j];
		DUMPBITS(j)
		    c->sub.code.need = c->dbits;
		c->sub.code.tree = c->dtree;
		Tracevv((stderr, "inflate:         length %u\n", c->len));
		c->mode = DIST;
	    case DIST:		/* i: get distance next */
		j = c->sub.code.need;
		NEEDBITS(j)
		    t = c->sub.code.tree + ((uInt) b & inflate_mask[j]);
		DUMPBITS(t->bits)
		    e = (uInt) (t->exop);
		if (e & 16)	/* distance */
		{
		    c->sub.copy.get = e & 15;
		    c->sub.copy.dist = t->base;
		    c->mode = DISTEXT;
		    break;
		}
		if ((e & 64) == 0)	/* next table */
		{
		    c->sub.code.need = e;
		    c->sub.code.tree = t + t->base;
		    break;
		}
		c->mode = BADCODE;	/* invalid code */
		z->msg = (char *)"invalid distance code";
		r = Z_DATA_ERROR;
		LEAVE
	    case DISTEXT:	/* i: getting distance extra */
		j = c->sub.copy.get;
		NEEDBITS(j)
		    c->sub.copy.dist += (uInt) b & inflate_mask[j];
		DUMPBITS(j)
		    Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
		c->mode = COPY;
	    case COPY:		/* o: copying bytes in window, waiting for space */
#ifndef __TURBOC__		/* Turbo C bug for following expression */
		f = (uInt) (q - s->window) < c->sub.copy.dist ?
		    s->end - (c->sub.copy.dist - (q - s->window)) :
		    q - c->sub.copy.dist;
#else
		f = q - c->sub.copy.dist;
		if ((uInt) (q - s->window) < c->sub.copy.dist)
		    f = s->end - (c->sub.copy.dist - (uInt) (q - s->window));
#endif
		while (c->len)
		{
		    NEEDOUT
			OUTBYTE(*f++)
			if (f == s->end)
			f = s->window;
		    c->len--;
		}
		c->mode = START;
		break;
	    case LIT:		/* o: got literal, waiting for output space */
		NEEDOUT
		    OUTBYTE(c->sub.lit)
		    c->mode = START;
		break;
	    case WASH:		/* o: got eob, possibly more output */
		if (k > 7)	/* return unused byte, if any */
		{
		    Assert(k < 16, "inflate_codes grabbed too many bytes")
			k -= 8;
		    n++;
		    p--;	/* can always return one */
		}
		FLUSH
		    if (s->read != s->write)
		    LEAVE
			c->mode = END;
	    case END:
		r = Z_STREAM_END;
		LEAVE
	    case BADCODE:	/* x: got error */
		r = Z_DATA_ERROR;
		LEAVE
	    default:
		r = Z_STREAM_ERROR;
		LEAVE
	}
Esempio n. 12
0
/* ********************************************************************   */
RTIP_BOOLEAN uart_hw_init(PUART_INFO uinfo)
{
#if (UART_16550)
byte baud_rate_divisor;
word port_base;
byte comm_irq;
byte temp_iir;
#if (DONT_OPEN_UART)
    return(TRUE);
#endif

#if (UART_SUPPORTS_HANDSHAKING)
    if (uinfo->handshake_type == 'R')
    {
#if (DEBUG_HANDSHAKING)
        DEBUG_ERROR("DOING R HANDSHAKING", NOVAR, 0, 0);
#endif
         uinfo->handshake_mask = UART_CTS;
         uinfo->holdoff_mask = (byte)(~UART_RTS);
         uinfo->resume_mask = UART_RTS;
    }
    else if (uinfo->handshake_type == 'D')
    {
       uinfo->handshake_mask = UART_DSR;
       uinfo->holdoff_mask = (byte)(~UART_DTR);
       uinfo->resume_mask = UART_DTR;
    }
    else
    {
       uinfo->handshake_mask = 0;
       uinfo->holdoff_mask = (byte)(~UART_DTR);
       uinfo->resume_mask = UART_DTR;
    }
#endif /* UART_SUPPORTS_HANDSHAKING */

    switch (uinfo->comm_port)
    {
    case 1 :
        port_base = 0x3F8;   /* I/O address for COM1  */
        comm_irq  =     4;   /* IRQ for COM1  */
        break;
    case 2 :
        port_base = 0x2F8;   /* I/O address for COM2  */
        comm_irq  =     3;   /* IRQ for COM2  */
        break;
    case 3 :
        port_base = 0x3E8;   /* I/O address for COM3  */
        comm_irq  =     4;   /* IRQ for COM3  */
        break;
    case 4 :
        port_base = 0x2E8;   /* I/O address for COM4  */
        comm_irq  =     3;   /* IRQ for COM4  */
        break;
    default:
        DEBUG_ERROR("uart_hw_init: illegal comm port: ", EBS_INT1, uinfo->comm_port, 0);
        return(FALSE);
    }

    /* ******                                                       */
    /* convert baud rate to divisor and check if baud rate is valid */
    switch (uinfo->baud_rate)
    {
    case 1152:
        baud_rate_divisor = 1;
        break;
    case 560:
        baud_rate_divisor = 2;
        break;
    case 384:
        baud_rate_divisor = 3;
        break;
    case 192:
        baud_rate_divisor = 6;
        break;
    case 96:
        baud_rate_divisor = 12;
        break;
    case 24:
        baud_rate_divisor = 48;
        break;
    case 12:
        baud_rate_divisor = 96;
        break;
    default:
        DEBUG_ERROR("uart_hw_init - bad baud rate = ", EBS_INT1, uinfo->baud_rate, 0);
        return(FALSE); /*  set_errno(EBADBAUD); */
    }

    /* Initialize UART                                   */
    /* interrupts were disabled already by the caller    */

    /* Set communication rate and parameters   */
    OUTBYTE(port_base + LCR, 0x80);   /* divisor access */
    io_delay();
    OUTBYTE(port_base + BRDL, baud_rate_divisor);
    io_delay();
    OUTBYTE(port_base + BRDH, 0);
    io_delay();
    OUTBYTE(port_base + LCR, 0x03);   /* divisor off, no parity, 1 stop bit, 8 bits */
    io_delay();

    /* Clear existing interrupts   */
    INBYTE(port_base + LSR);
    io_delay();
    INBYTE(port_base + MSR);
    io_delay();
    INBYTE(port_base + RBR);
    io_delay();

    /* Enable FIFO with receive interrupt after 8 char   */
    OUTBYTE(port_base + FCR, 0x87);
    io_delay();

    uinfo->xmit_fifo_size = 1;
    temp_iir = (byte)(INBYTE(port_base + IIR) & 0xf0);
    if (temp_iir == 0xc0)
    {
        DEBUG_ERROR("UART: 16550A", NOVAR, 0, 0);
        uinfo->is_16550=TRUE;
        uinfo->xmit_fifo_size = 16;
    }

    /* Enable read buffer full and receiver line status interrupts   */
    /* but not TX ints. Also enable modem status change INTS.        */
    
    OUTBYTE(port_base + IER, THRE_OFF);
    io_delay();

    /* cause uart_interrupt to execute when interrupt occurs and   */
    /* uart_receive to be called by the interrupt task             */
    ks_hook_interrupt(comm_irq, (PFVOID) 0, 
                      (RTIPINTFN_POINTER)uart_interrupt, 
                      (RTIPINTFN_POINTER) 0, uinfo->minor_number);
    io_delay();

    /* Enable interrupt signal and DTR    */
    OUTBYTE(port_base + MCR, 0x0b);   
    io_delay();

    uinfo->port_base=port_base;
    uinfo->comm_irq=comm_irq;
#else
#error: Set up any hardware dependent driver info here, and put it in UART_INFO
#endif
    return(TRUE);
}