static void local_put_char(int hub2, char ch)
{
	int flags = 0;

	if (hub2 < 0 || hub2 > 1) {
		printk("Error: Invalid serial port requested.\n");
		return; /* validate port op(UART 0|1) */
	}

	save_flags(flags); cli();

	while (!(UART_LSR(hub2) & UART_LSR_THRE)) {
		SYNC_ALL;
	}

	ACCESS_PORT_IER(hub2)
	UART_THR(hub2) = ch;
	SYNC_ALL;

	while (UART_LSR(hub2) & UART_LSR_THRE) {
		udelay(5);
	}

	restore_flags(flags);
}
Exemple #2
0
/*
* This Function Wait until Data RX Ready, and return Data Read from UART.
*/
uint8_t uart_read_timeout(uart_num_t uart_num, uint32_t rx_timeout_nb_cycles, uart_error_t* error)
{
	uint32_t uart_port;
	uint8_t uart_val;
	uint32_t counter;

	uart_port = uart_num;

	/* Wait Until Data Received (Rx Data Not Ready) */
	counter = 0;
	while ((UART_LSR(uart_port) & UART_LSR_RDR) == 0)
	{
		if (rx_timeout_nb_cycles>0) {
			counter++;
			if (counter>=rx_timeout_nb_cycles) {
				*error = UART_TIMEOUT_ERROR;
				return 0;
			}
		}
	}

	uart_val = (UART_RBR(uart_port) & UART_RBR_MASKBIT);

	/* Clear error */
	*error = UART_NO_ERROR;

	return uart_val;
}
Exemple #3
0
/*
* This Function return if data are received or not received.
*/
uart_rx_data_ready_t uart_rx_data_ready(uart_num_t uart_num)
{
	uint32_t uart_port;
	uint8_t uart_status;
	uart_rx_data_ready_t data_ready;

	uart_port = uart_num;

	uart_status = UART_LSR(uart_port) & 0xFF;

	/* Check Error */
	if ((uart_status & UART_LSR_ERROR_MASK) == 0) {
		/* No errors check if data is ready */
		if ((uart_status & UART_LSR_RDR) == 0) {
			data_ready = UART_RX_NO_DATA;
		} else {
			data_ready = UART_RX_DATA_READY;
		}
	} else {
		/* UART Error */
		data_ready = UART_RX_DATA_ERROR;
	}

	return data_ready;
}
/*
 * This is the serial driver's generic interrupt routine
 * Note: Generally it should be attached to general interrupt 10, responsile 
 *       for UART0&1 RCV and XMT interrupt, to make sure the invoked interrupt
 *       source, look into bit 10-13 of SIC_ISR(peripheral interrupt status reg.
 *       Finally, to see what can be done about request_irq(......)
 */
void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
	struct bf535_serial *info; // = &bf535_soft[CONFIG_SERIAL_CONSOLE_PORT];
	unsigned short iir; /* Interrupt Identification Register */
	unsigned short rx, idx;
	unsigned int sic_status = SIC_ISR;

	for (idx = 0; idx < NR_PORTS; idx++){
	   if (sic_status & (UART_INVOKED << 2*(idx + 5))){ 
	   	/* test bit 10-11 and 12-13 */
		iir = UART_IIR(idx);
		info = &bf535_soft[idx];

		if (!(iir & UART_IIR_NOINT)){
		   switch (iir & UART_IIR_STATUS){
		   case UART_IIR_LSR:
				printk("Line status changed for serial port %d.\n", idx);
				break;
		   case UART_IIR_RBR:
		   		/* Change access to IER & data port */
				ACCESS_PORT_IER(idx) 
				if (UART_LSR(idx) & UART_LSR_DR){
				   rx = UART_RBR(idx);
				   receive_chars(info, regs, rx);
				}
				break;
		   case UART_IIR_THR:
		   		/* Change access to IER & data port */
				ACCESS_PORT_IER(idx) 
				if (UART_LSR(idx) & UART_LSR_THRE){
				    transmit_chars(info);
//				    do{
//					transmit_chars(info);
//				    }while(info->xmit_cnt > 0);
				}
				break;
		   case UART_IIR_MSR:
				printk("Modem status changed for serial port.\n");
			
	   	   }
		}
	   }
	}	
void PutUARTByte (const char c)
{
    while (!(UART_READ32 (UART_LSR(g_uart)) & UART_LSR_THRE))
    {
    }

    if (c == '\n')
        UART_WRITE32 ((unsigned int) '\r', UART_THR(g_uart));

    UART_WRITE32 ((unsigned int) c, UART_THR(g_uart));
}
Exemple #6
0
/* This Function Wait Data TX Ready, and Write Data to UART 
	if rx_timeout_nb_cycles = 0 Infinite wait
*/
void uart_write(uart_num_t uart_num, uint8_t data)
{
	uint32_t uart_port;

	uart_port = uart_num;

	/* Wait Until FIFO not full  */
	while ((UART_LSR(uart_port) & UART_LSR_THRE) == 0);

	UART_THR(uart_port) = data;
}
Exemple #7
0
void rt_hw_console_output(const char* ptr)
{
	/* stream mode */
	while (*ptr)
	{
		if (*ptr == '\n')
		{
			/* FIFO status, contain valid data */
			while (!(UART_LSR(UART0_BASE) & (UARTLSR_TE | UARTLSR_TFE)));
			/* write data */
			UART_DAT(UART0_BASE) = '\r';
		}

		/* FIFO status, contain valid data */
		while (!(UART_LSR(UART0_BASE) & (UARTLSR_TE | UARTLSR_TFE)));
		/* write data */
		UART_DAT(UART0_BASE) = *ptr;

		ptr ++;
	}
}
Exemple #8
0
/*
* This Function Wait until Data RX Ready, and return Data Read from UART.
*/
uint8_t uart_read(uart_num_t uart_num)
{
	uint32_t uart_port;
	uint8_t uart_val;

	uart_port = uart_num;

	/* Wait Until Data Received (Rx Data Not Ready) */
	while ((UART_LSR(uart_port) & UART_LSR_RDR) == 0);

	uart_val = (UART_RBR(uart_port) & UART_RBR_MASKBIT);

	return uart_val;
}
int GetUARTBytes(u8 *buf, u32 size, u32 tmo_ms)
{
    u32 LSR;
    int tmo_en = (tmo_ms) ? 1 : 0;
    ulong start_time = get_timer(0);

    while (size) {
        if (tmo_en && (get_timer(start_time) > tmo_ms))
            break;

        /* kick watchdog to avoid cpu reset */
        if (!tmo_en)
            platform_wdt_kick();

        LSR = UART_READ32(UART_LSR(g_uart));
        if (LSR & UART_LSR_DR) {
            *buf++ = (u8)UART_READ32(UART_RBR(g_uart));
            size--;
        }
    }

    return (0 == size) ? 0 : -1;
}
Exemple #10
0
/*
* UART Init function
*/
void uart_init(uart_num_t uart_num,
				uart_databit_t data_nb_bits,
				uart_stopbit_t data_nb_stop,
				uart_parity_t data_parity,
				uint16_t uart_divisor,
				uint8_t uart_divaddval,
				uint8_t uart_mulval)
{
	uint32_t lcr_config;
	uint32_t uart_port;

	uart_port = uart_num;

	switch(uart_num)
	{
		case UART0_NUM:
			/* use PLL1 as clock source for UART0 */
			CGU_BASE_UART0_CLK = (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT) | (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT);
			break;

		case UART1_NUM:
			/* use PLL1 as clock source for UART1 */
			CGU_BASE_UART1_CLK = (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT) | (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT);
			break;

		case UART2_NUM:
			/* use PLL1 as clock source for UART2 */
			CGU_BASE_UART2_CLK = (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT) | (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT);
			break;

		case UART3_NUM:
			/* use PLL1 as clock source for UART3 */
			CGU_BASE_UART3_CLK = (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT) | (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT);
			break;

		default:
			return; /* error */
	}

	/* FIFOs RX/TX Enabled and Reset RX/TX FIFO (DMA Mode is also cleared) */
	UART_FCR(uart_port) = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS);
	/* Disable FIFO */
	UART_FCR(uart_port) = 0;

	// Dummy read (to clear existing data)
	while (UART_LSR(uart_port) & UART_LSR_RDR ) {
		dummy_read = UART_RBR(uart_port);
	}

	/* Wait end of TX & disable TX */
        UART_TER(uart_port) = UART_TER_TXEN;

        /* Wait for current transmit complete */
        while (!(UART_LSR(uart_port) & UART_LSR_THRE));

        /* Disable Tx */
        UART_TER(uart_port) = 0;

	/* Disable interrupt */
	UART_IER(uart_port) = 0;

	/* Set LCR to default state */
	UART_LCR(uart_port) = 0;

	/* Set ACR to default state */
	UART_ACR(uart_port) = 0;

	/* Dummy Read to Clear Status */
	dummy_read = UART_LSR(uart_port);

	/*
		Table 835. USART Fractional Divider Register:
		UARTbaudrate = PCLK / ( 16* (((256*DLM)+ DLL)*(1+(DivAddVal/MulVal))) )
		The value of MULVAL and DIVADDVAL should comply to the following conditions:
		1. 1 <= MULVAL <= 15
		2. 0 <= DIVADDVAL <= 14
		3. DIVADDVAL < MULVAL
	*/

	/* Set DLAB Bit */
	UART_LCR(uart_port) |= UART_LCR_DLAB_EN;
	UART_DLM(uart_port) = UART_LOAD_DLM(uart_divisor);
	UART_DLL(uart_port) = UART_LOAD_DLL(uart_divisor);
	/* Clear DLAB Bit */
	UART_LCR(uart_port) &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
	UART_FDR(uart_port) = (UART_FDR_MULVAL(uart_mulval) | UART_FDR_DIVADDVAL(uart_divaddval)) & UART_FDR_BITMASK;    

	/* Read LCR config & Force Enable of Divisor Latches Access */
	lcr_config = (UART_LCR(uart_port) & UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
	lcr_config |= data_nb_bits; /* Set Nb Data Bits */
	lcr_config |= data_nb_stop; /* Set Nb Stop Bits */
	lcr_config |= data_parity; /* Set Data Parity */

	/* Write LCR (only 8bits) */
	UART_LCR(uart_port) = (lcr_config & UART_LCR_BITMASK);

	/* Enable TX */
        UART_TER(uart_port) = UART_TER_TXEN;
}
static _INLINE_ void receive_chars(struct bf535_serial *info, struct pt_regs *regs, unsigned short rx)
{
	struct tty_struct *tty = info->tty;
	unsigned char ch;
	int idx = info->hub2;

	/*
	 * This do { } while() loop will get ALL chars out of Rx FIFO 
         */
	do {
		ch = (unsigned char) rx;
	
		if(info->is_cons) {
			if (UART_LSR(idx) & UART_LSR_BI){ /* break received */ 
				status_handle(info, UART_LSR(idx));
				return;
			} else if (ch == 0x10) { /* ^P */
				show_state();
				show_free_areas();
				show_buffers();
/*				show_net_buffers(); */
				return;
			} else if (ch == 0x12) { /* ^R */
				machine_restart(NULL);
				return;
			}
		}

		if(!tty){
			printk("no tty\n");
			goto clear_and_exit;
		}
		
		/*
		 * Make sure that we do not overflow the buffer
		 */
		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
			queue_task(&tty->flip.tqueue, &tq_timer);
			return;
		}

		if(UART_LSR(idx) & UART_LSR_PE) {
			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
			status_handle(info, UART_LSR(idx));
		} else if(UART_LSR(idx) & UART_LSR_OE) {
			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
			status_handle(info, UART_LSR(idx));
		} else if(UART_LSR(idx) & UART_LSR_FE) {
			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
			status_handle(info, UART_LSR(idx));
		} else {
			*tty->flip.flag_buf_ptr++ = 0; /* XXX */
		}

		tty->flip.count++;
                *tty->flip.char_buf_ptr++ = ch;

		ACCESS_PORT_IER(idx) /* change access to port data */
		rx = UART_RBR(idx);
	} while(UART_LSR(idx) & UART_LSR_DR);

	queue_task(&tty->flip.tqueue, &tq_timer);

clear_and_exit:
	return;
}