コード例 #1
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* TBD - move this to get_interrupt_type?   */
void uart_hw_clear_interrupt(PUART_INFO uinfo)
{
#if (UART_16550)
    INBYTE(uinfo->port_base + LSR); /* clear status interrupt */
    INBYTE(uinfo->port_base + MSR);
#endif
}
コード例 #2
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* ********************************************************************   */
void uart_get_status(PUART_INFO uinfo, PUART_STATUS uart_status)
{
#if (UART_16550)
byte msr;       /* modem status register */

    /* read the modem status register only once since reading it   */
    /* will clear it                                               */
    msr = INBYTE(uinfo->port_base + MSR);

#if (UART_SUPPORTS_HANDSHAKING)
    uart_status->tx_handshake = (RTIP_BOOLEAN)(msr & uinfo->handshake_mask);
#endif
#if (INCLUDE_MODEM)
    if (uinfo->flags & MODEM_CONNECTED)
    {
#    if (DEBUG_MODEM)
        DEBUG_ERROR("check for MODEM DROP", NOVAR, 0, 0);
#    endif
        uart_status->modem_drop   = (RTIP_BOOLEAN)(msr & UART_INV_DCD);
        if (uart_status->modem_drop)
            uinfo->flags &= ~MODEM_CONNECTED;
    }
    else
    {
        uart_status->modem_drop   = FALSE;
        uinfo->flags |= MODEM_CONNECTED;
    }
#endif
#else
#error: Implement checking if remote can recv or modem
#endif
}
コード例 #3
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* Return TRUE if there is space in the UARTs registers to hold transmit
data. Only called after a transmit or status interrupt happens. 
Return TRUE if there is space, FALSE if not.  This is useful for when
the UART has a FIFO that can be filled up multiple times on each tx 
interrupt. */
RTIP_BOOLEAN uart_hw_poll_tx(PUART_INFO uinfo)
{           
#if (UART_16550)
    return ((RTIP_BOOLEAN)(INBYTE(uinfo->port_base + LSR) & LSR_TBE));

#else
#error: Implement buffer checking for UART chip
#endif
}
コード例 #4
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* Checks to see if the data buffer in the UART has any data in it.  
   This is useful for UARTs with FIFOs, where one interrupt may 
   fire because the FIFO is full.  For UARTs with a one-byte FIFO,
   it suffices to just check and see if that's full.  If your
   UART does not have any method for checking its data buffer, then 
   something must be done.  We do not support this condition yet. */
RTIP_BOOLEAN uart_hw_poll_rx(PUART_INFO uinfo)
{ 
#if (UART_16550)
    return ((RTIP_BOOLEAN)(INBYTE(uinfo->port_base + LSR) & LSR_RXRDY));

#else
#error: Implement polling of the uart buffer
#endif
}
コード例 #5
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* Read one byte of data from the uart, and return it.
   Is only called after a transmit interrupt fires (i.e. 
   uart_hw_get_interrupt_type() returned UART_INPUT_INTERRUPT.) */
byte uart_hw_rx(PUART_INFO uinfo)
{
#if (UART_16550)
    return (byte) INBYTE(uinfo->port_base + RBR);

#else
#error: Implement retrieval of char from UART
#endif
}
コード例 #6
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
RTIP_BOOLEAN uart_hw_needs_servicing(PUART_INFO uinfo)
{
#if (UART_16550)
    uinfo->int_id=(word)INBYTE(uinfo->port_base+IIR);
    return ((RTIP_BOOLEAN)((uinfo->int_id & 0x0001) == 0));
#else 
#error: Implement interrupt polling or turn off SUPPORTS_INT_POLLING
#endif
}
コード例 #7
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* 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
}
コード例 #8
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* 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
}
コード例 #9
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
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
}
コード例 #10
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* 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 should return TRUE if the remote host is ready to receive
 data, FALSE otherwise. This function is called from the ISR. */
RTIP_BOOLEAN uart_hw_poll_tx_handshake(PUART_INFO uinfo)
{
dword msr_reg;
#if (UART_16550)
/*  return ((RTIP_BOOLEAN)(INBYTE(uinfo->port_base + MSR) & uinfo->handshake_mask));   */
    msr_reg = INBYTE(uinfo->port_base + MSR);
    if (!(msr_reg & uinfo->handshake_mask))
    {
        DEBUG_ERROR("uart_hw_poll_tx_handshake: msr, mask = ",
            DINT2, msr_reg, uinfo->handshake_mask);
    }
    return ((RTIP_BOOLEAN)(msr_reg & uinfo->handshake_mask));
#else
#error Implement checking if remote can recv
#endif
}
コード例 #11
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
int uart_hw_check_error(PUART_INFO uinfo)
{
#if (UART_16550)
byte err_flag = (byte)(INBYTE(uinfo->port_base + LSR) & 0x1eu);

    if (err_flag)
    {
        if (err_flag & LS_OVRRUN_ERR)   return 0;
        if (err_flag & LS_PARITY_ERR)   return 1;
        if (err_flag & LS_FRAME_ERR)    return 2;
    }
    io_delay();
    return -1;
#else
#error: Implement checking error status 
#endif
}
コード例 #12
0
ファイル: uart_ns16550.c プロジェクト: agatti/zephyr
static void set_baud_rate(struct device *dev, u32_t baud_rate)
{
	const struct uart_ns16550_device_config * const dev_cfg = DEV_CFG(dev);
	struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev);
	u32_t divisor; /* baud rate divisor */
	u8_t lcr_cache;

	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 */
		lcr_cache = INBYTE(LCR(dev));
		OUTBYTE(LCR(dev), LCR_DLAB | lcr_cache);
		OUTBYTE(BRDL(dev), (unsigned char)(divisor & 0xff));
		OUTBYTE(BRDH(dev), (unsigned char)((divisor >> 8) & 0xff));

		/* restore the DLAB to access the baud rate divisor registers */
		OUTBYTE(LCR(dev), lcr_cache);

		dev_data->baud_rate = baud_rate;
	}
コード例 #13
0
ファイル: UARTPORT.C プロジェクト: Strongc/DC_source
/* ********************************************************************   */
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);
}